2012-10-03 3 views
1

나는이 별도의 SQL 쿼리를하고 난 그들이 다른 방법을 알아낼 수 없습니다SQL 쿼리 문

SELECT A.AccountName, 
     T.Total 
FROM ACCOUNTS A 
     LEFT OUTER JOIN (SELECT * 
         FROM Totals 
         WHERE PersonID = @PersonID 
           AND Yr = @Year) T 
     ON A.AccountID = T.AccountID 
ORDER BY AccountName 

SELECT A.AccountName, 
     T.Total 
FROM ACCOUNTS A 
     LEFT OUTER JOIN (SELECT * 
         FROM Totals) T 
     ON A.AccountID = T.AccountID 
WHERE PersonID = @PersonID 
     AND Yr = @Year 
ORDER BY AccountName 

어떤 도움을 주시면 감사하겠습니다.

+0

@MartinSmith SQL을 자동으로 들여 쓰기하는 도구가 있습니까? 그것은 끔찍한 빠른 편집이었다. – NullUserException

+0

@NullUserException - 예. SQL Pretty Printer 사본이 있습니다. [여기에 온라인 버전이 있습니다] (http://www.dpriver.com/pp/sqlformat.htm) –

+0

Nope. 그냥 –

답변

1

첫 번째 쿼리는 계정에 @Year 및 @Person 값과 일치하는 총 레코드가 있는지 (또는 총 레코드와 전혀 일치하지 않는지 여부와 관계없이) 모든 계정 레코드에 대한 결과 만 표시합니다. 일치하지 않는 레코드의 Total 열에는 NULL이 있지만 모든 계정에 대해 결과가 표시됩니다. 두 번째 쿼리는 연도와 사람과 일치하는 합계가있는 계정 만 표시합니다. 일치하는 항목이 없으면 계정 레코드가 결과에 전혀 표시되지 않습니다.

그리고 2 개 쿼리가 정말 더 다음과 같이 작성해야합니다 (여기에 하위 쿼리에 대한 필요) :

SELECT A.AccountName, T.Total 
FROM ACCOUNTS A 
LEFT JOIN Totals T 
     ON A.AccountID = T.AccountID AND T.PersonID = @PersonID AND T.Yr = @Year 
ORDER BY AccountName 

SELECT A.AccountName, T.Total 
FROM ACCOUNTS A 
LEFT JOIN Totals T ON A.AccountID = T.AccountID 
WHERE T.PersonID = @PersonID AND T.Yr = @Year 
ORDER BY AccountName 

위의 코드는 원본 기능적으로 동일합니다.

마지막으로, 당신은 더 이런 식으로 뭔가를 할 수 있습니다 같은 소리 : 당신이 당신의 년과 사람의 조건을 어디다

이 쿼리에서
SELECT A.AccountName, T.Total 
FROM Accounts A 
INNER JOIN Totals T ON T.AccountID = A.AccountID 
WHERE T.PersonID = @PersonID AND T.Yr = @Year 

, 그것은 중요하지 않습니다. 쿼리는 동일한 결과를 나타냅니다. 계정 레코드는 합계 레코드와 원하는 연도 및 사람이 일치하는 경우에만 표시됩니다. 일치하지 않는 계정은 결과에 전혀 표시되지 않습니다.

1

외부 조인 (두 번째 쿼리) 후에 WHERE 조건을 적용하면 잠재적으로 결과 집합에서 레코드가 제거됩니다. 첫 번째 쿼리에는 ACCOUNTS 테이블의 모든 행이 포함됩니다. 인


는 제 쿼리에서 반환 표 Totals 테이블에 일치하는 데이터가 존재하지 NULL들과 함께 ACCOUNTS 테이블의 모든 레코드에 대해 적어도 하나의 행을 가질 것이다. Totals 테이블에 일치하는 항목이 여러 개인 경우 ACCOUNT에 대한 여러 행이 표시됩니다.

두 번째 쿼리는 매개 변수와 일치하는 ACCOUNTS의 행만 반환하며 일치하는 행은 Totals이어야합니다.

+0

그렇다면 출력은 어떻게 생깁니 까? –

+0

결과 세트에 대한 설명으로 나의 대답을 업데이트했습니다. –

0

OUTER JOIN 테이블에 간단한 절을 넣을 때마다 조건을 테스트하기 전에 외부 테이블이 있는지 테스트해야합니다. 그렇지 않으면 실용적인 측면에서 외부 조인을 내부 조인으로 변환해야합니다. 내 경우 :

-- original 
SELECT A.AccountName, T.Total 
FROM ACCOUNTS A 
LEFT OUTER JOIN (SELECT * 
    FROM Totals 
    WHERE PersonID = @PersonID 
    AND Yr = @Year 
) T ON A.AccountID = T.AccountID 
ORDER BY AccountName; 

-- modified with same result 
SELECT A.AccountName, T.Total 
FROM ACCOUNTS A 
LEFT OUTER JOIN Totals T ON A.AccountID = T.AccountID 
WHERE (1=2 -- syntactic sugar 
    OR (T.AccountID IS NULL) -- this prevents outer joined rows to be excluded 
    OR (T.PersonID = @PersonID AND T.Yr = @Year) -- original filter 
) 
ORDER BY AccountName;