다른 테이블에 조건이 있는 테이블의 왼쪽 조인
나는 여러 테이블에 참여하고 두 번째 테이블에 참여할 때 세 번째 테이블에 조항을 두려고 합니다.저는 where 절을 사용해 보았지만 두 번째 테이블의 열을 무효화하고 싶을 때 전체 결과에 적용됩니다.
예를 들어, 그것은 더 명확해질 것입니다.나는 4개의 테이블이 있습니다.
CREATE TABLE A (ID INTEGER PRIMARY KEY);
CREATE TABLE B (ID INTEGER PRIMARY KEY, A_ID INTEGER, C_ID INTEGER, D_ID INTEGER);
CREATE TABLE C (ID INTEGER PRIMARY KEY, CONDITIONS INTEGER);
CREATE TABLE D (ID INTEGER PRIMARY KEY, CONDITIONS INTEGER);
테이블 B가 테이블 A를 테이블 C와 D에 연결합니다.
샘플 데이터는 다음과 같습니다.
INSERT INTO A VALUES (1);
INSERT INTO A VALUES (2);
INSERT INTO A VALUES (3);
INSERT INTO C VALUES (1, 1);
INSERT INTO C VALUES (2, 1);
INSERT INTO C VALUES (3, 0);
INSERT INTO D VALUES (1, 0);
INSERT INTO D VALUES (2, 0);
INSERT INTO B VALUES (1, 1, 1, NULL);
INSERT INTO B VALUES (2, 1, 2, NULL);
INSERT INTO B VALUES (3, 1, 3, NULL);
INSERT INTO B VALUES (4, 2, NULL, 1);
INSERT INTO B VALUES (5, 2, NULL, 2);
왼쪽으로 직접 조인:
SELECT A.ID, B.ID, C.ID, D.ID
FROM A
LEFT JOIN B ON B.A_ID = A.ID
LEFT JOIN C ON B.C_ID = C.ID
LEFT JOIN D ON B.D_ID = D.ID;
데이터를 반환합니다.
╔══════╦══════╦══════╦══════╗
║ A.id ║ B.id ║ C.id ║ D.id ║
╠══════╬══════╬══════╬══════╣
║ 1 ║ 1 ║ 1 ║ null ║
║ 1 ║ 2 ║ 2 ║ null ║
║ 1 ║ 3 ║ 3 ║ null ║
║ 2 ║ 4 ║ null ║ 1 ║
║ 2 ║ 5 ║ null ║ 2 ║
║ 3 ║ null ║ null ║ null ║
╚══════╩══════╩══════╩══════╝
제가 하려는 것은 C 테이블과 D 테이블의 데이터로 B 테이블을 필터링하는 것입니다.요청에 단순히 where 조건을 추가하는 경우:
SELECT A.ID, B.ID, C.ID, D.ID
FROM A
LEFT JOIN B ON B.A_ID = A.ID
LEFT JOIN C ON B.C_ID = C.ID
LEFT JOIN D ON B.D_ID = D.ID
WHERE (C.ID IS NULL OR C.CONDITIONS = 1)
AND (D.ID IS NULL OR D.CONDITIONS = 1);
반환되는 항목:
╔══════╦══════╦══════╦══════╗
║ A.id ║ B.id ║ C.id ║ D.id ║
╠══════╬══════╬══════╬══════╣
║ 1 ║ 1 ║ 1 ║ null ║
║ 1 ║ 2 ║ 2 ║ null ║
║ 3 ║ null ║ null ║ null ║
╚══════╩══════╩══════╩══════╝
그건 논리적이지만 내가 원하는 것은 아닙니다.제가 원하는 것은:
╔══════╦══════╦══════╦══════╗
║ A.id ║ B.id ║ C.id ║ D.id ║
╠══════╬══════╬══════╬══════╣
║ 1 ║ 1 ║ 1 ║ null ║
║ 1 ║ 2 ║ 2 ║ null ║
║ 2 ║ null ║ null ║ null ║
║ 3 ║ null ║ null ║ null ║
╚══════╩══════╩══════╩══════╝
그것은 그들과 계속 어울립니다.A.ID = 2
그러나 C와 D의 일치 조건을 가진 B 값을 찾을 수 없습니다.
나는 조건을 넣으려고 노력했습니다.ON
C 및 D 테이블에 결합하는 절이지만 B에서 데이터는 데이터를 유지합니다.
╔══════╦══════╦══════╦══════╗
║ A.id ║ B.id ║ C.id ║ D.id ║
╠══════╬══════╬══════╬══════╣
║ 1 ║ 1 ║ 1 ║ null ║
║ 1 ║ 2 ║ 2 ║ null ║
║ 1 ║ 3 ║ null ║ null ║
║ 2 ║ 4 ║ null ║ null ║
║ 2 ║ 5 ║ null ║ null ║
║ 3 ║ null ║ null ║ null ║
╚══════╩══════╩══════╩══════╝
저는 이제 그 묘기를 부릴 생각이 없습니다.
당신이 해야 할 일은 왼쪽 외측 접합입니다.b
의 테이블.c
그리고.d
테이블 먼저, 그리고 나서 바깥쪽은 그것을 다시 연결합니다.a
표 값이 다음 중 하나에 존재하는 경우c
또는d
조건 열.이와 같은 경우:
SELECT a.id a_id, b2.b_id, b2.c_id, b2.d_id
FROM a
LEFT OUTER JOIN (SELECT b.id b_id,
b.a_id,
c.id c_id,
d.id d_id
FROM b
LEFT OUTER JOIN c ON b.c_id = c.id AND c.conditions = 1
LEFT OUTER JOIN d ON b.d_id = d.id AND d.conditions = 1) b2
ON a.id = b2.a_id AND COALESCE(b2.c_id, b2.d_id) IS NOT NULL
ORDER BY a.id, b2.b_id, b2.c_id, b2.d_id;
A_ID B_ID C_ID D_ID
---------- ---------- ---------- ----------
1 1 1
1 2 2
2
3
(편집된 출력물에서 문제를 발견해 준 Alex Pool에게 감사드립니다!)
ETA:
이는 다음과 같이 기록될 수도 있습니다.
SELECT a.id a_id, b.id b_id, c.id c_id, d.id d_id
FROM a
LEFT OUTER JOIN (b
LEFT OUTER JOIN c ON b.c_id = c.id AND c.conditions = 1
LEFT OUTER JOIN d ON b.d_id = d.id AND d.conditions = 1)
ON a.id = b.a_id AND COALESCE(c.id, d.id) IS NOT NULL
ORDER BY a.id, b.id, b.c_id, b.d_id;
이는 더 간단하지만 잠재적으로 의도를 해독하기가 더 어렵습니다(따라서 향후 유지 관리가 더 어렵습니다).이것이 유효한 구문인지 전혀 몰랐기 때문에 여기에 추가했습니다. 그러면 더 잘 작동한다고 느낄 수 있습니다.
제가 이전 것을 틀린 것으로 삭제했기 때문에 다른 답변을 추가합니다.저는 이것이 올바른 논리라고 생각합니다.
SELECT A.ID, B.ID, C.ID, D.ID
FROM A LEFT JOIN
(B LEFT JOIN
C
ON B.C_ID = C.ID AND C.CONDITIONS = 1 LEFT JOIN
D
ON B.D_ID = D.ID AND D.CONDITIONS = 1
)
ON B.A_ID = A.ID AND
(C.ID IS NOT NULL OR D.ID IS NOT NULL);
이것은 제가 테스트했을 때 정확한 결과를 반환합니다.
그것은 흥미로운 문제입니다.이 아이디어는 괄호를 사용하여 비교를 "지연"하는 것입니다.A
그리고.B
이를 통해 조건이 일치하는지 여부도 판단할 수 있습니다.C
또는D
.
사실 나는 하위 쿼리로 그것을 하는 다른 방법을 찾았습니다.ON
절:
SELECT A.ID, B.ID, C.ID, D.ID
FROM A
LEFT JOIN B ON B.A_ID = A.ID
AND (B.C_ID IS NULL OR B.ID IN (SELECT B.ID FROM B JOIN C ON C.ID = B.C_ID AND C.CONDITIONS = 1)
AND (B.D_ID IS NULL OR B.ID IN (SELECT B.ID FROM B JOIN D ON D.ID = B.D_ID AND D.CONDITIONS = 1)
LEFT JOIN C ON B.C_ID = C.ID
LEFT JOIN D ON B.D_ID = D.ID;
어떤 솔루션이 A 테이블과 B, C, D 테이블에 다른 조항이 있으면 더 잘 수행될지 모르겠습니다.
언급URL : https://stackoverflow.com/questions/42972753/left-join-on-a-table-with-condition-on-others-table
'programing' 카테고리의 다른 글
Sublime Text와 같이 PyCharm에서 선택한 텍스트를 둘러싸는 방법 (0) | 2023.08.20 |
---|---|
jQuery로 내부 텍스트를 변경하려면 어떻게 해야 합니까? (0) | 2023.08.20 |
HTML 양식 게시를 위한 XMLHttp 요청 (0) | 2023.08.20 |
크롬/사파리가 플렉시블 부모의 높이를 100% 채우지 않음 (0) | 2023.08.20 |
PHP가 이미 데이터베이스에 연결되어 있는지 확인하려면 어떻게 해야 합니까? (0) | 2023.08.20 |