source

WHERE 조건에 비해 JOIN 절을 사용하는 이유는 무엇입니까?

manysource 2023. 8. 8. 21:42

WHERE 조건에 비해 JOIN 절을 사용하는 이유는 무엇입니까?

Oracle 데이터베이스를 기반으로 개발합니다.최대 절전 모드와 같은 ORM을 사용하지 않고 수동으로 써야 할 때는 조인 대신 WHERE 조건을 사용합니다.

예를 들어, 스타일을 설명하기 위해 단순화됩니다.

Select *
from customers c, invoices i, shipment_info si
where c.customer_id = i.customer_id
    and i.amount > 999.99 
    and i.invoice_id = si.invoice_id(+)  -- added to show a replacement for a join
order by i.amount, c.name

저는 이 스타일을 Old Oracle DBA로부터 배웠습니다.그 이후로 저는 이것이 표준 SQL 구문이 아니라는 것을 알게 되었습니다.비표준적이고 데이터베이스 이동성이 훨씬 떨어지는 것 외에 이 형식을 사용하는 데 다른 영향이 있습니까?

그 않습니다. 어떤 스타일인지 때문입니다. 어떤 스타일인지 결정하기가 어렵기 때문입니다.WHERE절은 시뮬레이션을 위한 것입니다.JOINs그리고 어떤 것이 실제 필터를 위한 것인지, 그리고 나는 프로그래머의 원래 의도를 결정하는 것을 불필요하게 어렵게 만드는 코드를 좋아하지 않습니다.

내가 이 형식에서 마주친 가장 큰 문제는 일부 가입을 잊어버리는 경향입니다.WHERE절을 사용하여 데카르트 곱을 생성합니다.이는 쿼리에 새 테이블을 추가할 때 특히 일반적입니다(적어도 저는 그렇습니다).예를 들어, 다음과 같이 가정합니다.ADDRESSES테이블은 혼합물에 던져지고 당신의 마음은 약간 건망증이 납니다.

SELECT *
  FROM customers c, invoices i, addresses a
 WHERE c.customer_id = i.customer_id
   AND i.amount > 999.99
 ORDER BY i.amount, c.name

붐! 데카르트 제품! :)

기존 스타일의 조인이 완전히 잘못된 경우도 있습니다(외부 조인이 원인입니다).내측 조인을 사용할 때는 거의 동일하지만 외측 조인에서 특히 외측 조인이 null일 수 있는 경우 잘못된 결과를 생성할 수 있습니다.이는 이전 구문을 사용할 때 전체 결과 집합이 구성될 때까지 조인 조건이 논리적으로 평가되지 않으므로 일치하는 레코드가 없기 때문에 열이 null일 수 있을 때 레코드를 필터링할 조인 외부에서 열에 대한 조건을 표현할 수 없기 때문입니다.

예를 들어,

모든 고객을 선택하고 송장이 처리된 8월의 모든 송장에 대한 위젯 매출 합계(청구서)를 선택합니다.프로세스 날짜가 null이 아님)

새로운 ANSI-92 가입 구문 사용

 Select c.name, Sum(d.Amount)
 From customer c
    Left Join Invoice I 
        On i.custId = c.custId
            And i.SalesDate Between '8/1/2009' 
                      and '8/31/2009 23:59:59'
            And i.ProcessDate Is Not Null
    Left Join InvoiceDetails d 
        On d.InvoiceId = i.InvoiceId
            And d.Product = 'widget'
 Group By c.Name

이전 구문을 사용하여 이 작업을 수행해 보십시오.이전 스타일 구문을 사용하는 경우 '외부' 행이 다시 추가되기 전에 where 절의 모든 조건이 평가/적용되므로 모든 처리되지 않은 송장 행이 최종 결과 집합에 다시 추가됩니다...따라서 기존 구문에서는 불가능합니다. 처리된 날짜가 null인 송장을 필터링하려고 하면 고객이 제거됩니다.유일한 대안은 상관된 하위 쿼리를 사용하는 것입니다.

어떤 사람들은 이 스타일이 덜 읽기 쉽다고 말할 것이지만, 그것은 습관의 문제입니다.성능 측면에서는 쿼리 최적화 도구가 이를 처리하기 때문에 문제가 되지 않습니다.

그 이후로 저는 이것이 표준 SQL 구문이 아니라는 것을 알게 되었습니다.

그건 사실이 아닙니다."a,b where" ansi-89 표준,"a join b on"구문은 ansi-92입니다.그러나 89 구문은 더 이상 사용되지 않으므로 새 쿼리에 사용하면 안 됩니다.

또한, 특히 외부 조인이나 복잡한 쿼리와 관련하여 오래된 스타일에 표현력이 부족한 경우도 있습니다.

조인 조건을 선택하기 위해 where 조항을 통과하는 것은 고통일 수 있습니다.하나 이상의 가입을 위해 낡은 스타일은 절대적으로 사악합니다.그리고 일단 새로운 스타일을 알게 되면, 그냥 계속 사용하는 것이 좋습니다.

이것은 표준 SQL 구문이며 JOIN보다 오래된 표준입니다.구문이 발전한 데는 다음과 같은 이유가 있으므로 최신 JOIN 구문을 사용해야 합니다.

  1. 보다 표현력이 뛰어나며 조인된 테이블, 조인 순서, 조인에 적용되는 조건을 명확하게 표시하고 필터링 조건과 조인 조건을 구분합니다.

  2. LEFT, RIGHT 및 FULL OUTER JOIN을 지원하지만 WHERE 구문에서는 지원하지 않습니다.

WHERE 형식의 JOIN은 JOIN 구문보다 이식성이 크게 떨어지는 것을 발견하지 못할 것이라고 생각합니다.

당신이 ANSI 자연 결합 기능을 사용하지 않는 한 저는 괜찮습니다.

Scott Cher의 말에 전적으로 동의합니다.

나는 WHERE 구문이 INNER JOIN보다 읽기 쉽다고 생각합니다. 베지마이트와 비슷한 것 같습니다.세상의 대부분의 사람들은 아마 그것을 역겹다고 생각하겠지만, 그것을 먹고 자란 아이들은 그것을 좋아합니다.

습관에 따라 다르지만, 저는 항상 Oracle의 쉼표로 구분된 구문이 더 자연스럽다고 생각했습니다.첫 번째 이유는 (내부) JOIN을 사용하면 가독성이 떨어진다고 생각하기 때문입니다.두 번째는 유연성입니다.결국 조인은 정의상 데카르트 곱입니다.두 테이블의 ID를 기준으로 결과를 제한할 필요는 없습니다.매우 드물지만 두 테이블의 데카르트 곱이 필요할 수도 있습니다.ID를 기준으로 제한하는 것은 매우 합리적인 방법일 뿐 규칙이 아닙니다. 그러나 JOIN 키워드를 사용하는 경우 등이 해당됩니다.SQL Server에서는 ON 키워드를 생략할 수 없습니다.조합 리스트를 생성하려고 합니다.다음과 같이 해야 합니다.

SELECT *
FROM numbers
JOIN letters
ON 1=1

그 외에도 오라클의 (+) 구문도 매우 합리적이라고 생각합니다."이 레코드가 null인 경우에도 결과 집합에 추가하십시오."라고 말하는 것이 좋습니다.이것은 오른쪽/왼쪽 조인 구문보다 훨씬 낫습니다. 왜냐하면 사실 왼쪽이나 오른쪽이 없기 때문입니다.여러 유형의 외부 조인으로 10개의 테이블을 조인하려는 경우 "왼쪽"에 있는 테이블과 오른쪽에 있는 테이블이 혼동됩니다.

그런데, 좀 더 일반적인 의견으로서, 저는 SQL 이식성이 더 이상 현실 세계에 존재하지 않는다고 생각합니다.표준 SQL이 너무 빈약하고 다양한 DBMS 특정 구문의 표현력이 너무 자주 요구되기 때문에 100% 휴대용 SQL 코드는 달성 가능한 목표라고 생각하지 않습니다.제가 관찰한 가장 확실한 증거는 오래된 행 번호가 문제가 있다는 것입니다.SO를 포함한 "sql번호"에 대한 포럼을 검색하기만 하면 특정 DBMS에서 어떻게 달성할 수 있는지 묻는 수백 개의 게시물을 볼 수 있습니다. 예를 들어, 반환되는 를 제한하는 것도 유사합니다.

이것은 Transact SQL 구문이며, 얼마나 "휴대하기 어려운" 구문인지 잘 모르겠습니다. 예를 들어 Sybase(Sybase는 ANSI 구문도 지원)뿐만 아니라 다른 많은 데이터베이스(전부는 아닐지라도)에서 사용되는 주요 구문입니다.

ANSI 구문의 주요 이점은 T-SQL이 금지하는 상당히 까다로운 체인 조인을 작성할 수 있다는 것입니다.

자동화된 SQL 쿼리 변환기(인라인 뷰 확장, 그래프트된 조인, 유니온 팩터링)를 작성하고 SQL을 조작할 데이터 구조로 생각하는 사람으로서, 비 JOIN 구문은 조작하기에 훨씬 덜 고통스럽습니다.저는 "더 읽기 어려운" 불평에 대해 말할 수 없습니다. JOIN은 관계형 대수 연산자에 대한 돌진처럼 보입니다.거기 가지 마 :-)

사실 이 구문은 JOIN보다 더 휴대성이 좋습니다. 왜냐하면 거의 모든 데이터베이스에서 작동하지만 모든 사람이 JOIN 구문을 지원하는 것은 아닙니다(예를 들어, [최근에 변경되지 않은 경우]).

언급URL : https://stackoverflow.com/questions/1613304/why-use-a-join-clause-versus-a-where-condition