문제
사용자가 문서를 다운로드했는지 여부를 나타내는 열이 포함 된 쿼리를 구성하려고합니다. ID, DocumentID, MemberID라는 다음 열에 HASDOWNLODID라는 테이블이 있습니다. 사용자가 다운로드했는지 여부를 찾으십시오 특정한 문서는 쉽습니다. 그러나 결과가 다음과 같이 보이는 쿼리를 생성해야합니다.
name id
----------------------
abc NULL
bbb 2
ccc 53
ddd NULL
eee 13
ID는 정말 중요하지 않습니다. 내가 관심있는 것은 문서가 다운로드되었는지 여부입니다 (NULL 여부).
다음은 내 쿼리입니다.
SELECT Documents.name, HasDownloaded.id FROM Documents
LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id
WHERE HasDownloaded.memberID = @memberID
문제는 hasdownloaded 테이블에 지정된 사용자에 대한 항목이 존재하는 경우에만 값을 반환한다는 것입니다. 나는 이것을 간단하게 유지하고 싶습니다. 가지다 다운로드되었습니다. 따라서 사용자 1이 ABC, BBB 및 CCC를 다운로드 한 경우에도 DDD와 EEE가 결과 테이블에 NULL로 표시되기를 원합니다. 그러나 Where 절은 나에게 항목이 존재하는 값 만 제공합니다.
나는 SQL 전문가가 많지 않습니다. 여기서 내가 원하는 것을 줄 운영자가 있습니까? 다른 접근 방식을 취해야합니까? 아니면 이것이 불가능합니까?
해결책
WHERE 절의 조건을 조정 조건으로 이동하십시오.
SELECT Documents.name, HasDownloaded.id FROM Documents
LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id
AND HasDownloaded.memberID = @memberID
이것은 where 절이 될 왼쪽 조인식 테이블을 참조하려고 할 때마다 필요합니다.
다른 팁
WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId
그렇게하는 일반적인 방법 일 것입니다. 일부는 다음과 같이 단축 할 것입니다.
WHERE COALESCE(HasDownloaded.memberId, @memberId) = @memberId
Matt B.가 보여주는 것처럼 가입 조건에서 할 수는 있지만 사람들을 혼란스럽게 할 가능성이 훨씬 높다고 생각합니다. 조인 절로 이동하는 것이 왜 작동하는지 이해하지 못하면, 나는 그것을 멀리하는 것을 강력히 제안 할 것을 강력히 제안합니다.
@mark : Join Syntax가 작동하는 이유를 이해하지만 경고에 감사드립니다. 나는 당신의 제안이 더 직관적이라고 생각합니다. 나는 어느 것이 더 효율적인지 궁금했다. 그래서 나는 빠른 테스트를 실행했습니다 (이것은 다소 단순했습니다. 14 개의 행과 10 개의 시험 만 두려워합니다).
조인 조건에서 :
AND HasDownloaded.memberID = @memberID
- 클라이언트 처리 시간 : 4.6
- 총 실행 시간 : 35.5
- 서버 회신의 대기 시간 : 30.9
WHERE 절에서 :
WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId
- 클라이언트 처리 시간 : 7.7
- 총 실행 시간 : 27.7
- 서버 회신의 대기 시간 : 22.0
WHERE 절이 더욱 효율적으로 보입니다. 흥미로운! 다시 한번, 여러분 모두에게 도움을 주셔서 감사합니다.