排名前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'
使用OUTER APPLY而不是LEFT JOIN:
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。
debugging像这样的情况的关键是运行在其自己的子查询/内联视图来查看输出是什么:
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
值不匹配,这就解释了为什么任何mbg
引用都会返回null
(感谢左连接;如果是内连接,你不会得到任何东西join)。
您已经使用TOP
自己编码到了一个angular落,因为现在如果要为其他用户运行查询,则必须调整该查询。 更好的方法是:
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'
这样,您可以更改where
子句中的id
值来检查系统中任何用户的logging。
因为来自有序子查询的TOP 1
没有profile_id = 'u162231993'
删除where u.id = 'u162231993'
,然后查看结果。
分别运行子查询以了解发生了什么。
达米尔是正确的,
你的子查询需要确保dps_user.id等于um.profile_id,否则它将抓住最上面一行,但可能不等于你的“u162231993”
你的查询应该是这样的:
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'