Postgresql

確保 GROUP 具有特定的值,而不是聚合

  • October 12, 2017

我有一張桌子(a :: text, b :: uuid)

我還有一UUID (不是列表,即順序無關緊要)bs = {b1, b2, b3},.

我怎樣才能得到這樣一個表a中恰好有這三個bs的,不多也不少?

就像是:

SELECT tt.a
 FROM (SELECT a, sort(array_agg(b)) AS bs FROM t GROUP BY a) AS tt
 WHERE tt.bs = sort('{b1, b2, b3}')

但這似乎是一個相當糟糕的主意,以提高效率……

我想你想要這樣的東西..

SELECT a
FROM tt
GROUP BY a
HAVING array_agg(b ORDER BY b) = ARRAY[
 -- whatever
]::uuid[];

樣本數據,

CREATE TABLE tt ( a text, b uuid DEFAULT gen_random_uuid() );
INSERT INTO tt(a) VALUES ('foo'), ('bar'), ('baz'), ('foo'), ('foo');

SELECT a, b FROM tt ORDER BY a,b;
 a  |                  b                   
-----+--------------------------------------
bar | 6a7d1d36-d16f-459c-9fb0-b5a54f1fc5b3
baz | 2fca5dee-4bfe-4862-9b8a-79890fbfda28
foo | 32f9d608-f87f-4830-b0d8-6215f60a71ee
foo | 3fe0cffe-446e-4e94-8785-2f893ee91a0c
foo | f9d07c5a-e69b-4501-a441-5bbd86ed7f4b
(5 rows)

這將返回foo

SELECT a
FROM tt
GROUP BY a
HAVING array_agg(b ORDER BY b) = ARRAY[
 '32f9d608-f87f-4830-b0d8-6215f60a71ee',
 '3fe0cffe-446e-4e94-8785-2f893ee91a0c',
 'f9d07c5a-e69b-4501-a441-5bbd86ed7f4b'
]::uuid[];

但是,如果沒有這三件事,並且沒有更多的東西,array_agg那麼你將不會得到匹配。

如果您不關心多餘的匹配,也就是說,如果 foo 具有額外的 UUId 應該返回匹配,您可以通過將它們複製到將使用索引的附加 where 子句來優化此表達式。

害羞,如果你需要更快,你可以使用物化視圖,或者也寫一個計數子句……

HAVING count(*) = ...
 AND array_agg(b ORDER BY b) = ...

引用自:https://dba.stackexchange.com/questions/188350