2016-08-29 2 views
2

의 모든 행 나는 하나 개의 특정 시나리오에서 SQL을 사용하여 데이터를 검색하는 몇 가지 문제에 직면하고있는 행을 검색합니다SQL은 다른 테이블

한다고 가정 나는 다음과 같은 테이블이 있습니다

  • A (ID, attr_a을, attr_b);
  • B (id, attr_d, attr_e);
  • C (id_a, id_b);

당신이 볼 수 있듯이, 테이블 CFK 테이블 A에서 ID를 참조하고, 테이블 C에서 ID를 참조합니다.

A 행마다 B 행과 관련된 테이블 A 행을 검색해야합니다. 나는 다음

+1

a 및 b? – Baahubali

+0

@ user1490835 a와 b는 관계가 없으므로 내부 조인을 사용할 수 없습니다. 또한 모든 B ID가있는 행만 원하므로 조인이 작동하지 않아 더 제한적이어야합니다. –

+1

'a와 b 관계를 가지지 마라. '예, 테이블 C를 통해. 물론 @TimBiegeleisen도 –

답변

1

모든 권한을 가진 사용자 만 얻고 싶은 것 A 가정 실제 생활 시나리오에서

는 사용자가 B이 권한을 의미합니다 의미하고, C이 권한을 사용자에게 관련된 많은 개체에 많은입니다 쿼리는 주어진 ID에 대해 B 테이블의 모든 레코드와 일치하는 모든 A 레코드를 반환해야합니다. A에 모든 전체 레코드를 반환하려면 하위 쿼리가 필요합니다. A.id 기본 키 (또는 적어도 고유의) C.id_a에 의해 참조되는 열로서이기 때문에

SELECT t1.* 
FROM A t1 
INNER JOIN 
(
    SELECT A.id 
    FROM A 
    INNER JOIN C 
     ON A.id = C.id_a 
    GROUP BY A.id 
    HAVING COUNT(*) = (SELECT COUNT(*) FROM B) 
) t2 
    ON t1.id = t2.id 
2
select A.* 
from A 
join C on id_a = id 
group by id 
having count(id) = (select count(*) from B) 

하위 쿼리를 사용할 필요가 없습니다.

1

FK 제약 조건에 의해 적용되는 참조 무결성을 가정하면 모든 키 열 NOT NULL(id_a, id_b)의 UNIQUE 또는 PK 제약 조건은 C입니다. 당신이 필요로하는 모든 ID가있는 경우

, 전용 테이블 C와 함께 작동합니다. A에 합류 시간을 낭비하지 마십시오

SELECT id_a 
FROM C 
GROUP BY 1 
HAVING count(*) = (SELECT count(*) FROM B); 

당신이 A에서 열 또는 전체 행을해야 할 경우,가 집계 및 비 자격 행을 제거 후 에 가입 할 수 있습니다. 가장 빠를 것.

SELECT A.* 
FROM (
    SELECT id_a AS id 
    FROM C 
    GROUP BY 1 
    HAVING count(*) = (SELECT count(*) FROM B) 
    ) c 
JOIN A USING (id); 
0

원하는 권한이 모든 권한을 가진 사용자 목록 인 경우 실제로는 테이블 C 만 있으면됩니다. 이에 대한 한 가지 방법은 하나의 문자열로 C.id_aC.id_b 사이의 페어링에 보이는 CONCAT 함께 :

SELECT C.id_a 
FROM C 
GROUP BY C.id_a 
HAVING COUNT(DISTINCT CONCAT(C.id_a, C.id_b)) = 
(SELECT COUNT(DISTINCT C.id_b) 
    FROM C) 

현재 테스트 : 당신은 계산 할 필요가 없습니다 http://sqlfiddle.com/#!9/f92a54/3

0

, 당신은 확인해야합니다 (비 존재 행 :

SELECT * 
FROM A 
WHERE NOT EXISTS (
     SELECT * FROM B 
     WHERE NOT EXISTS (
       SELECT * FROM C 
       WHERE C.id_a = A.id AND C.id_b = B.id 
       ) 
     );