我有两张桌子,T1和T2如下:
CATEGORY ID
1 1100
1 1200
1 1300
1 1500
2 2000
2 2100
2 2300
2 2500
我需要知道:
从今天早晨开始,我就紧紧抓住它,并尝试这样做以获得类似的行:
select count(*) from T1, T2 WHERE
T1.CATEGORY = T2.CATEGORY AND T1.ID = T2.ID;
但我无法弄清楚如何获得唯一的行(仅在T1或T2中)。
答案 0 :(得分:5)
问题1
SELECT COUNT(*) totalCount
FROM T1 a
INNER JOIN T2 b
ON a.Category = b.Category AND
a.ID = b.ID
问题2(使用LEFT JOIN
)
SELECT COUNT(*) totalCount
FROM T2 a
LEFT JOIN T1 b
ON a.Category = b.Category AND
a.ID = b.ID
WHERE b.Category IS NULL
问题3(使用LEFT JOIN
)
SELECT COUNT(*) totalCount
FROM T1 a
LEFT JOIN T2 b
ON a.Category = b.Category AND
a.ID = b.ID
WHERE b.Category IS NULL
答案 1 :(得分:1)
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)
;
这些查询为类别== 1,2构建“位掩码”1,为类别== 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
答案 2 :(得分:0)
如果您不能假设行是不同的,那么您需要采取稍微不同的方法。这是一个同时回答所有三个问题的方法,考虑到重复的行:
select (case when isT1 = 1 and isT2 = 0 then 'BOTH'
when isT1 = 1 then 'T1-Only'
else 'T2-Only'
end) as WhereRow,
count(*) as NumDistinctRows,
sum(cnt) as NumTotalRows
from ((select category, id, count(*) as cnt, 1 as isT1, 0 as isT2
from t1
group by category, id
) union all
(select category, id, count(*) as cnt, 0 as isT1, 1 as isT2
from t2
group by category, id
)
) t
group by isT1, isT2