2010-03-12 5 views
4

JOIN 키워드를 사용할 때 조건부를 사용해야하는지 알고 싶습니다.JOIN 키워드를 사용할 때 두 조건을 추가하는 것이 좋은 방법입니까?

날짜별로이 결과 집합을 필터링하려고하는데 WHERE 절을 사용하는 날짜에 대한 비용이나 수입이 없더라도 나열된 모든 분기를 가져올 수 없습니다. 이 경우 더 나은 방법이 있습니까?

SELECT 
    Branches.Name 
    ,SUM(Expenses.Amount) AS Expenses 
    ,SUM(Incomes.Amount) AS Incomes 
FROM 
    Branches 
    LEFT JOIN Expenses 
    ON Branches.Id = Expenses.BranchId AND Expenses.Date = '3/11/2010' 
    LEFT JOIN Incomes 
    ON Branches.Id = Incomes.BranchId AND Incomes.Date = '3/11/2010' 
GROUP BY Branches.Name 

답변

5

왜 안 되니? 더 나아가! OUTER JOIN에는이 두 가지 조건에 대한 매우 구체적인 트릭이 있습니다! INNER JOIN 는 다음 예를 들어, 상응 재조합에 관대하다 :

INNER JOIN Expenses 
    ON Branches.Id = Expenses.BranchId 
WHERE 
    Expenses.Date = '3/11/2010' 

들을 통해

INNER JOIN Expenses 
    ON Branches.Id = Expenses.BranchId AND Expenses.Date = '3/11/2010' 

을 BUT !!! OUTER JOIN의 경우 ON 내부에 정확히 두 조건을 지정해야합니다. WHERE 결과를 INNER JOIN으로 처리해야합니다.

+0

그럼 'Expenses.Date ='3/11/2010 'OR Expenses.Date IS NULL'라고 쉽게 말할 수 있습니다. 이것은 실제로 트릭이 아니며 논리적 인 행동입니다. –

+0

절대적으로 맞으면, 'ON'과 'WHERE'사이의 외부 조인에는 미묘한 차이가 있습니다. +1 – incarnate

+0

@Paul : Expenses.Date가 Null을 허용하지 않는 경우에만. –

2

외부 결합을 조건 지정하는 올바른 방법입니다.

당신은 한 쿼리가 ExpensesIncomes 테이블의 BranchIdDate 분야 모두에 대해 인덱스를 사용할 수있는, 어떤 성능 문제가 없어야합니다.

-1

제 생각에는 조인 논리와 필터링을 분리해야합니다.

SELECT 
    Branches.Name 
    ,SUM(Expenses.Amount) AS Expenses 
    ,SUM(Incomes.Amount) AS Incomes 
FROM 
    Branches 
    LEFT JOIN Expenses 
    ON Branches.Id = Expenses.BranchId 
    LEFT JOIN Incomes 
    ON Branches.Id = Incomes.BranchId 
WHERE ISNULL(Expenses.Date,'3/11/2010') = '3/11/2010' 
AND ISNULL(Incomes.Date,'3/11/2010') = '3/11/2010' 
GROUP BY Branches.Name 
+1

대부분의 경우 왼쪽 조인을 수행 할 때 쿼리의 JOIN에서 WHERE 섹션으로 조건부를 이동하면 매우 다른 결과가 나타납니다. 이 변경을 권고 할 때주의하십시오. –

+0

그러면 왼쪽 조인이 내부 조인으로 변경되고 잘못된 결과 집합이 반환됩니다. 아주 가난한 생각. – HLGEM

+0

충분히 공정하게, 당신은 절대적으로 옳다. 나는 그것을 타이핑하면서 왼쪽 조인이라는 사실을 완전히 놓쳤다! 나는 그것을 지금 바꿨다. 나는 여전히 나는 원칙적으로 옳다고 생각한다. 위의 쿼리가 여전히 NULL 날짜와 일치 할 수 있는지 명확하지 않다. –

0

제대로하고 있습니다. 귀하의 경우, 조인의 오른쪽을 필터링하여 날짜 조건이 조인에 속하게 될 것으로 예상하고 있습니다. "저에게 모든 지점을주고, 내 조건에 맞는 소득이 &입니다."

조건을 WHERE 절로 이동하면 쿼리의 전체 의미가 "모든 지점과 해당 수익 & 비용을 제공하지만 모든 조건이 내 조건과 일치하는 경우에만"변경됩니다.

이것은 좋은 연습 문제는 아니지만 데이터베이스가 쿼리를 평가하는 방법과 관련되어 있습니다.

0

외부 조인을 사용할 때 이렇게하는 가장 좋은 방법입니다. 추가 조건을 where 절로 이동하면 모든 레코드에서 where 조건을 충족시켜야하므로 조인이 내부 조인으로 변경됩니다.

0

위의 쿼리가 정확합니다.

  • 조건이 WHERE 절에

    , 그것은 결과에 만족 이 당신의 왼쪽에있는 NULL 행 (가입 것을 의미을 설정할 수있는 기준이다, 예를 들어 : 여기가 바로 그것을 유지하는 방법입니다)는 일치하지 않으며 제외됩니다. 기준이 가입 절에서 (왼쪽 또는 오른쪽 중 하나)이다
  • , 그것은 결과에에 가입 있지만 만족 수있다 기준입니다. 행이 있으면 조건을 충족해야하지만 실제로 평가할 상대방에 값이 없더라도 SQL은 OUTER JOIN이 일치로 간주되도록 허용합니다.그게 더 의미가있는 경우

는 잘 모르겠어요,하지만 일치가없는 경우에도 행을 반환하고자하는 당신의 경우에, 당신의 기준에 있어야 가입 (위 그것을 한 적이으로) .

관련 문제