왼쪽 조인을 적용하기 전에 테이블 필터링


82

2 개의 테이블이 있는데 2 개의 테이블이 결합 되기 전에 1 개의 테이블을 필터링하고 싶습니다 .

고객 테이블 :

   ╔══════════╦═══════╗
   ║ Customer ║ State ║
   ╠══════════╬═══════╣
   ║ A        ║ S     ║
   ║ B        ║ V     ║
   ║ C        ║ L     ║
   ╚══════════╩═══════╝

엔트리 테이블 :

   ╔══════════╦═══════╦══════════╗
   ║ Customer ║ Entry ║ Category ║
   ╠══════════╬═══════╬══════════╣
   ║ A        ║  5575 ║ D        ║
   ║ A        ║  6532 ║ C        ║
   ║ A        ║  3215 ║ D        ║
   ║ A        ║  5645 ║ M        ║
   ║ B        ║  3331 ║ A        ║
   ║ B        ║  4445 ║ D        ║
   ╚══════════╩═══════╩══════════╝

Entry 테이블에 관련 레코드가 있는지 여부에 관계없이 Customer 테이블에서 모든 레코드를 가져 오도록 Left Join을 원합니다. 그러나 조인 전에 항목 테이블에서 범주 D를 필터링하고 싶습니다 .

원하는 결과 :

   ╔══════════╦═══════╦═══════╗
   ║ Customer ║ State ║ Entry ║
   ╠══════════╬═══════╬═══════╣
   ║ A        ║ S     ║  5575 ║
   ║ A        ║ S     ║  3215 ║
   ║ B        ║ V     ║  4445 ║
   ║ C        ║ L     ║  NULL ║
   ╚══════════╩═══════╩═══════╝

다음 쿼리를 수행하는 경우 :

   SELECT Customer.Customer, Customer.State, Entry.Entry
   FROM Customer
   LEFT JOIN Entry
   ON Customer.Customer=Entry.Customer
   WHERE Entry.Category='D'

이것은 마지막 레코드를 필터링합니다.

따라서 왼쪽 테이블의 모든 행을 카테고리 D로 필터링 된 항목 테이블에 조인합니다.

사전에 도움을 주셔서 감사합니다!


이 링크를 참조하십시오 -sqlbenjamin.wordpress.com/2017/12/23/…
MasterJoe

답변:


115

WHERE필터를 JOIN조건 으로 이동해야합니다 .

SELECT c.Customer, c.State, e.Entry
FROM Customer c
LEFT JOIN Entry e
   ON c.Customer=e.Customer
   AND e.Category='D'

데모로 SQL Fiddle 보기


1
와우 빠르고 효율적입니다! 도움을 주셔서 감사합니다!
Tom Jenkin 2013

8
@TomJenkin 감사합니다. 사이트에 환상적인 첫 번째 질문을 게시했습니다. 많은 세부 사항 등
Taryn

감사합니다.이 사이트를 즐겁게 사용할 수있을 것 같습니다. 언젠가 자신처럼 기여할 수 있기를 바랍니다. D
Tom Jenkin 2013

2
@bluefeet이지만 두 실행 계획은 동일하지 않습니까?
Alex Zhukovskiy

1
where 조건이 첫 번째 테이블을 가리키는 경우 조인 전에 조인이 종속 된 테이블에 필터링을 적용합니다. 적어도 내 테스트에서 나는 그것을 보았다. 나는 Alex의 의견에 대한 답변으로 그 의견을 게시했습니다.
Áxel Costas Pena

28

다음을 수행 할 수도 있습니다.

SELECT c.Customer, c.State, e.Entry
FROM Customer AS c
LEFT JOIN (SELECT * FROM Entry WHERE Category='D') AS e
ON c.Customer=e.Customer

여기에 SQL Fiddle


3
@TomJenkin 늦게 응답 해 주셔서 죄송합니다. 저는 이번 내내 컴퓨터에서 떨어져있었습니다. 하지만 궁금해서이 두 가지를 모두 실행하고 실행 계획을 확인했습니다. 실행 계획은 거의 동일하지만 어느 쪽이 더 좋은지 Bluefeet의 버전 인 것으로 보입니다.
Jeff Rosenberg

이것이 제 사건을 고치도록 영감을주었습니다.
sivann

1

또는...

SELECT c.Customer, c.State, e.Entry
FROM Customer c
LEFT JOIN Entry e
   ON c.Customer=e.Customer
WHERE e.Category IS NULL or e.Category='D'

SQL에서 JOIN 조건은 WHERE 전에 실행됩니다. 따라서 제안 된 솔루션에서는 전체 테이블이 조인되고 결과가 필터링되므로 큰 테이블을 처리 할 때 비용이 많이들 수 있습니다. 의도 된 필터 조건은 다른 답변에서 제안 된 것과 같이 JOIN 조건의 일부 여야합니다
Omley

@Omley SQL 작동 방식에 대해 혼란스러워하는 것 같습니다. SQL은 절차 적이 지 않고 선언적 입니다. 단어의 순서 쿼리는에 아무런 영향이 없습니다 작업의 순서를 . 그것은 엔진에 달려 있습니다. 우리는 MySql이 실제로 Taryn의 답변보다이 쿼리를 최적화하는 데 매우 미미하게 더 잘 수행된다는 것을 알 수 있습니다 . 그러나 이것은 확실히 관리보다 운이 좋을 것이고 그 반대는 다른 엔진에 대해서도 사실 일 수 있습니다. EXPLAIN
cz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.