Postgresql
選擇按“附加”指示器分組的行
我有一個(預先存在的,不,我不是這樣設計的!)這樣的模式/數據集:
CREATE TABLE t(id,name,seq,addon,kind) AS VALUES ( 1234::int, 'A' , 345::int, 'f'::bool, 'c' ), ( 1235 , NULL, 346 , 't' , NULL ), ( 1236 , NULL, 347 , 't' , NULL ), ( 2345 , 'B' , 348 , 'f' , 'x' ), ( 2346 , NULL, 349 , 't' , NULL ), ( 3456 , 'C' , 350 , 'f' , 'c' ), ( 3457 , NULL, 351 , 't' , NULL );
在哪裡:
- “id”欄位只是一個 SQL 序列(不保證順序)
- “seq”欄位保證在整個表格中是連續的,例如表格通常在此列上排序。
- “addon”欄位表示一組相關條目,例如,TRUE 條目與最近的具有較低“seq”的 FALSE 條目相關。
我想選擇所有帶有“kind”=‘x’的行及其所有關聯的“addon”行,而不為其他種類獲取任何其他“addon”行。
例如:
SELECT * FROM t WHERE kind = 'x' AND ???
會給我:
id | name | seq |addon | kind | ------+------+------+------+------+... 2345 | "B" | 348 | f | "x" | 2346 | | 349 | t | |
我有 PostgreSQL 9.6…
您只需要創建一個真正的分組。這裡我們使用一個視窗函式
count(x)
來計算所有的東西NOT NULL
。試試這個簡化的例子,SELECT count(a) OVER () FROM ( VALUES (true),(false) ) AS t(a);
為了計算我們想要
OR
的,如果 lhs 不是,我們使用 which 評估 rhstrue
。所以在這裡我們測試是否行IS FALSE
(如果值為假則返回真),如果條件不評估為真(意味著值為真或空)我們返回null
(所以count(x)
跳過它)。這是完整的查詢,SELECT *, count((addon IS FALSE) OR NULL) OVER (ORDER BY seq) AS grp FROM t id | name | seq | addon | kind | grp ------+------+-----+-------+------+----- 1234 | A | 345 | f | c | 1 1235 | | 346 | t | | 1 1236 | | 347 | t | | 1 2345 | B | 348 | f | x | 2 2346 | | 349 | t | | 2 3456 | C | 350 | f | c | 3 3457 | | 351 | t | | 3 (7 rows)
現在你可以輕鬆地做任何你想做的事情了..
WITH t AS ( SELECT *, count((addon IS FALSE) OR NULL) OVER (ORDER BY seq) AS grp FROM t ) SELECT * FROM t AS t1 WHERE EXISTS ( SELECT 1 FROM t AS t2 WHERE addon IS FALSE AND kind = 'x' AND t1.grp = t2.grp ) ORDER BY seq;
要在其他地方查看此模式,請使用此搜尋查看gaps-and-islands和postgresql