왼쪽 조인 포함 상위 1위
아래 쿼리에서 dps_markers에 동일한 마커 키를 가진 여러 행이 있을 수 있지만 첫 번째 행에 대해서만 참여하려고 합니다.이 쿼리를 사용하여 상위 1과 ORDER BY를 삭제하면 mbg.marker_value 값이 표시되지만 그대로 실행되면 항상 null이 반환됩니다.
SELECT u.id, mbg.marker_value
FROM dps_user u
LEFT JOIN
(SELECT TOP 1 m.marker_value, um.profile_id
FROM dps_usr_markers um (NOLOCK)
INNER JOIN dps_markers m (NOLOCK)
ON m.marker_id= um.marker_id AND
m.marker_key = 'moneyBackGuaranteeLength'
ORDER BY m.creation_date
) MBG ON MBG.profile_id=u.id
WHERE u.id = 'u162231993'
LEFT JOIN 대신 Outer APPLY:
SELECT u.id, mbg.marker_value
FROM dps_user u
OUTER APPLY
(SELECT TOP 1 m.marker_value, um.profile_id
FROM dps_usr_markers um (NOLOCK)
INNER JOIN dps_markers m (NOLOCK)
ON m.marker_id= um.marker_id AND
m.marker_key = 'moneyBackGuaranteeLength'
WHERE um.profile_id=u.id
ORDER BY m.creation_date
) AS MBG
WHERE u.id = 'u162231993';
JOIN과 달리 APPLY를 사용하면 내부 쿼리 내의 u.id을 참조할 수 있습니다.
다음과 같은 상황을 디버깅할 때 중요한 것은 서브쿼리/인라인 뷰를 단독으로 실행하여 출력 결과를 확인하는 것입니다.
SELECT TOP 1
dm.marker_value,
dum.profile_id
FROM DPS_USR_MARKERS dum (NOLOCK)
JOIN DPS_MARKERS dm (NOLOCK) ON dm.marker_id= dum.marker_id
AND dm.marker_key = 'moneyBackGuaranteeLength'
ORDER BY dm.creation_date
그것을 실행해 보면, 당신은 이 모든 것이profile_id
값이 일치하지 않음u.id
의 가치u162231993
그 이유를 설명해주죠mbg
참조가 반환됩니다.null
(왼쪽 조인트 덕분에 안쪽 조인트라면 아무것도 얻을 수 없습니다).
당신은 자신을 코너에 몰아넣고TOP
다른 사용자에 대해 쿼리를 실행하려면 쿼리를 조정해야 하기 때문입니다.보다 나은 접근법은 다음과 같습니다.
SELECT u.id,
x.marker_value
FROM DPS_USER u
LEFT JOIN (SELECT dum.profile_id,
dm.marker_value,
dm.creation_date
FROM DPS_USR_MARKERS dum (NOLOCK)
JOIN DPS_MARKERS dm (NOLOCK) ON dm.marker_id= dum.marker_id
AND dm.marker_key = 'moneyBackGuaranteeLength'
) x ON x.profile_id = u.id
JOIN (SELECT dum.profile_id,
MAX(dm.creation_date) 'max_create_date'
FROM DPS_USR_MARKERS dum (NOLOCK)
JOIN DPS_MARKERS dm (NOLOCK) ON dm.marker_id= dum.marker_id
AND dm.marker_key = 'moneyBackGuaranteeLength'
GROUP BY dum.profile_id) y ON y.profile_id = x.profile_id
AND y.max_create_date = x.creation_date
WHERE u.id = 'u162231993'
이 기능을 사용하면,id
값어치where
시스템 내 모든 사용자의 레코드를 체크하기 위한 구를 지정합니다.
왜냐하면TOP 1
명령된 하위 항목에서profile_id = 'u162231993'
제거한다.where u.id = 'u162231993'
결과를 볼 수 있습니다.
서브쿼리를 개별적으로 실행하여 상황을 파악합니다.
다미르 말이 맞아요
서브쿼리에서는 dps_user.id가 um.profile_id와 동일한지 확인해야 합니다.그렇지 않으면 u162231993의 ID와 동일하지는 않을 수 있지만 맨 위 행이 나타납니다.
쿼리는 다음과 같습니다.
SELECT u.id, mbg.marker_value
FROM dps_user u
LEFT JOIN
(SELECT TOP 1 m.marker_value, um.profile_id
FROM dps_usr_markers um (NOLOCK)
INNER JOIN dps_markers m (NOLOCK)
ON m.marker_id= um.marker_id AND
m.marker_key = 'moneyBackGuaranteeLength'
WHERE u.id = um.profile_id
ORDER BY m.creation_date
) MBG ON MBG.profile_id=u.id
WHERE u.id = 'u162231993'
언급URL : https://stackoverflow.com/questions/2033699/top-1-with-a-left-join
'source' 카테고리의 다른 글
ARC와 호환되는 Objective-C 싱글톤을 구현하려면 어떻게 해야 하나요? (0) | 2023.04.24 |
---|---|
FormBuilder 컨트롤의 수동 값 설정 (0) | 2023.04.24 |
행 및 열 인덱스로 WPF 그리드의 제어에 프로그래밍 방식으로 액세스하는 방법은 무엇입니까? (0) | 2023.04.19 |
커밋 메시지로 Git 저장소를 검색하는 방법 (0) | 2023.04.19 |
SwiftUI - 뷰에 하드코딩된 네비게이션을 피하는 방법 (0) | 2023.04.19 |