支援版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.18. intagg — 整數聚合器與列舉器 #

intagg 模組提供了一個整數聚合器和一個列舉器。 intagg 現在已過時,因為有一些內建函數提供了其功能的超集合。但是,該模組仍然作為內建函數的相容性包裝器提供。

F.18.1. 函數 #

聚合器是一個彙總函數 int_array_aggregate(integer),它產生一個整數陣列,其中包含它所接收到的所有整數。 這是 array_agg 的包裝器,對於任何陣列類型,它都可以執行相同的操作。

列舉器是一個函數 int_array_enum(integer[]),它返回 setof integer。 它本質上是聚合器的反向操作:給定一個整數陣列,將其展開為一組列。 這是 unnest 的包裝器,對於任何陣列類型,它都可以執行相同的操作。

F.18.2. 使用範例 #

許多資料庫系統都有多對多表格的概念。 這樣的表格通常位於兩個索引表格之間,例如

CREATE TABLE left_table  (id INT PRIMARY KEY, ...);
CREATE TABLE right_table (id INT PRIMARY KEY, ...);
CREATE TABLE many_to_many(id_left  INT REFERENCES left_table,
                          id_right INT REFERENCES right_table);

它通常像這樣使用

SELECT right_table.*
FROM right_table JOIN many_to_many ON (right_table.id = many_to_many.id_right)
WHERE many_to_many.id_left = item;

這將返回右手表格中,左手表格中某個項目的所有項目。 這是 SQL 中非常常見的結構。

現在,如果 many_to_many 表格中有大量條目,這種方法可能會很麻煩。 通常,像這樣的聯結會導致索引掃描,並為表格中特定左手項目的每個右手條目進行提取。 如果您有一個非常動態的系統,您就無能為力。 但是,如果您有一些相當靜態的資料,您可以使用聚合器建立摘要表格。

CREATE TABLE summary AS
  SELECT id_left, int_array_aggregate(id_right) AS rights
  FROM many_to_many
  GROUP BY id_left;

這將建立一個表格,每個左手項目一行,以及一個右手項目的陣列。 現在,如果沒有某種使用陣列的方法,這是非常沒用的; 這就是為什麼會有陣列列舉器的原因。 您可以執行

SELECT id_left, int_array_enum(rights) FROM summary WHERE id_left = item;

使用 int_array_enum 的上述查詢會產生與

SELECT id_left, id_right FROM many_to_many WHERE id_left = item;

不同之處在於,針對摘要表格的查詢只需要從表格中取得一行,而針對 many_to_many 的直接查詢必須為每個條目進行索引掃描和提取一行。

在一個系統上,一個 EXPLAIN 顯示,成本為 8488 的查詢已降低到成本為 329。 原始查詢是一個涉及 many_to_many 表格的聯結,該表格已被

SELECT id_right, count(id_right) FROM
  ( SELECT id_left, int_array_enum(rights) AS id_right
    FROM summary
    JOIN (SELECT id FROM left_table
          WHERE id = item) AS lefts
    ON (summary.id_left = lefts.id)
  ) AS list
  GROUP BY id_right
  ORDER BY count DESC;

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的地方,請使用 此表格回報文件問題。