2012-12-22 2 views
0

내가 두 테이블, 다음과 같은 T1과 T2가에서 독특하고 일반적인 행 수 :선택은 두 테이블

  • 을 T1과 T2 사이의 유사 얼마나 많은 행 :

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

    나는 알 필요가 (동일한 카테고리와 ID) T2에서

  • 행수가 T1에없는 T1에서
  • 얼마나 많은 행
01,235 T2에없는 16,

가 오늘 아침 이후에 머리를 집재과 유사한 행을 얻기 위해 그렇게하려고 노력 해요 :

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

을하지만 난 단지 T1에 (고유 행을 얻을 방법을 알아낼 수 없습니다 또는 T2).

답변

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 
+0

전문가들은 내가 FULL JOIN'는 MySQL을 지원하지 않습니다 '생각하는 빠른 :-) – vels4j

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 
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, 그들을 추가하십시오. 그래서 마스크는 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 
+0

답변을 제공합니다. –

+0

답변 해 주셔서 감사합니다. 하지만 우리는 1 천만 개의 원시 코드를 가지고 있으며 실제로 메모리를 소비합니다. – madkitty

+0

3 가지 질문에 하나의 쿼리로 대답하는 유일한 방법입니다. 10M 행은 여기에서 관련이 없습니다. * 모든 솔루션은 ID에 대한 일종의 색인의 이점을 누릴 수 있습니다. – wildplasser