Diberikan kueri di bawah ini mungkin ada beberapa baris di dps_markers dengan kunci penanda yang sama tetapi kami hanya ingin menggabungkan yang pertama. Jika saya mengambil kueri ini dan menghapus 1 teratas dan ORDER BY saya mendapatkan nilai untuk mbg.marker_value tetapi jalankan seperti itu selalu mengembalikan 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'
sql-server
outer-join
dstarh
sumber
sumber
Kunci untuk men-debug situasi seperti ini adalah dengan menjalankan subquery / inline view sendiri untuk melihat keluarannya:
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
Dengan menjalankan itu, Anda akan melihat bahwa
profile_id
nilainya tidak cocok denganu.id
nilai dariu162231993
, yang akan menjelaskan mengapambg
referensi akan dikembalikannull
(berkat left join; Anda tidak akan mendapatkan apa pun jika itu adalah inner join).Anda telah mengkodekan diri Anda sendiri ke sudut menggunakan
TOP
, karena sekarang Anda harus mengubah kueri jika Anda ingin menjalankannya untuk pengguna lain. Pendekatan yang lebih baik adalah: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'
Dengan itu, Anda dapat mengubah
id
nilai dalamwhere
klausa untuk memeriksa catatan untuk setiap pengguna di sistem.sumber
Karena
TOP 1
dari sub-kueri yang diurutkan tidak memilikiprofile_id = 'u162231993'
Hapuswhere u.id = 'u162231993'
dan lihat hasilnya.Jalankan sub-kueri secara terpisah untuk memahami apa yang terjadi.
sumber
Damir benar,
Subkueri Anda perlu memastikan bahwa dps_user.id sama dengan um.profile_id, jika tidak maka akan mengambil baris teratas yang mungkin, tapi mungkin tidak sama dengan id Anda dari 'u162231993'
Kueri Anda akan terlihat seperti ini:
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'
sumber
WHERE um.profile_id = 'u162231993'
sub-query danWHERE mbg.marker_value IS NOT NULL
di luar.@SearchFor = 'u162231993'
dan kemudian gunakan diWHERE
, atau posting beberapa data dan struktur tabel sehingga orang lain dapat membantu dan mencobanya.