DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;
CREATE TABLE lutser
( id INTEGER NOT NULL
, category INTEGER NOT NULL
);
INSERT INTO lutser(category, id) VALUES
(1,1100) ,(1,1200) ,(1,1300) ,(1,1500)
,(2,2000) ,(2,2100) ,(2,2300) ,(2,2500)
,(1,3500) -- added these
,(2,3500)
;
这些查询为 category==1 构造一个“位掩码”1,为 category==2 构造一个 2,并将它们相加。因此,当 id 出现在两个集合中时,掩码为 3,仅在第一个集合中为 1,仅在第二个集合中为 2。外部联接+合并在这里起到了作用。
--
-- CTE version
--
WITH flags AS (
WITH one AS ( SELECT category AS flag , id FROM lutser WHERE category = 1)
, two AS ( SELECT category AS flag , id FROM lutser WHERE category = 2)
SELECT COALESCE(one.flag, 0) + COALESCE(two.flag, 0) AS flag
FROM one
FULL OUTER JOIN two ON two.id = one.id
)
SELECT flag, COUNT(*)
FROM flags
GROUP BY flag;
--
-- Non-CTE version
--
SELECT COALESCE(one.flag, 0) + COALESCE(two.flag, 0) AS flags
, COUNT(*)
FROM (
SELECT category AS flag , id
FROM lutser WHERE category = 1
) one
FULL OUTER JOIN (
SELECT category AS flag , id
FROM lutser WHERE category = 2
) two ON two.id = one.id
GROUP BY flags;
结果(对于两个查询;-):
flags | count
-------+-------
1 | 4
2 | 4
3 | 1