0

我有两个表,T1 和 T2 如下:

CATEGORY     ID
1           1100
1           1200
1           1300
1           1500 
2           2000
2           2100
2           2300
2           2500

我需要知道 :

  • T1 和 T2 之间有多少行相似(相同的 CATEGORY 和 ID)
  • T2 中有多少行不在 T1 中
  • T1 中有多少行不在 T2 中

从今天早上开始,我就一直在努力,并试图这样做以获得类似的行:

select count(*) from T1, T2 WHERE 
T1.CATEGORY = T2.CATEGORY AND T1.ID = T2.ID; 

但我不知道如何获得唯一的行(仅在 T1 或 T2 中)。

4

3 回答 3

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
于 2012-12-22T14:46:11.280 回答
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)
        ;

这些查询为 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
于 2012-12-22T16:50:00.050 回答
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
于 2012-12-22T15:46:59.450 回答