Postgresql
確保 GROUP 具有特定的值,而不是聚合
我有一張桌子
(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) = ...