如何修改SQL查询,关联三表获取每个Partyid对应最大Smplandt的行
解决每个Party仅返回最大Smplandt对应行的SQL问题
问题说明
表结构
- Partymain表:Partyid(主键)、Partyname
- Smplanmain表:Smplanid(主键)、Smplandt
- Smplandet表:Smplandetid(主键)、Smplanid(外键)、Partyid、slotno、elotno
需求
以Partymain表为基础左连接其他表,获取每个Party对应最大Smplandt的单条数据,输出字段为:Partyid、Partyname、Smplandt、Slotno、Elotno。
原SQL的问题在于子查询未做筛选,导致每个Party返回多条数据,以下是修正方案:
方案1:使用窗口函数(推荐)
通过ROW_NUMBER()窗口函数按Partyid分组,对Smplandt降序排序,只保留每组的第一条数据(即Smplandt最大的行):
SELECT p.partyid, p.partyname, ISNULL(s.smplandt, '') AS smplandt_last, ISNULL(s.slotno, '') AS slotno_last, ISNULL(s.elotno, '') AS elotno_last FROM Partymain p LEFT JOIN ( SELECT b.partyid, a.smplandt, b.slotno, b.elotno, ROW_NUMBER() OVER (PARTITION BY b.partyid ORDER BY a.smplandt DESC) AS rn FROM Smplandet b INNER JOIN Smplanmain a ON b.smplanid = a.smplanid ) s ON p.partyid = s.partyid AND s.rn = 1 ORDER BY UPPER(p.partyname)
如果同一Party存在多条拥有相同最大Smplandt的记录,且需要保留所有这些行,可将ROW_NUMBER()替换为RANK()或DENSE_RANK()。
方案2:子查询筛选最大日期后关联
先找出每个Party的最大Smplandt,再关联回原表获取对应字段:
SELECT p.partyid, p.partyname, ISNULL(a.smplandt, '') AS smplandt_last, ISNULL(b.slotno, '') AS slotno_last, ISNULL(b.elotno, '') AS elotno_last FROM Partymain p LEFT JOIN ( SELECT b.partyid, MAX(a.smplandt) AS max_smplandt FROM Smplandet b INNER JOIN Smplanmain a ON b.smplanid = a.smplanid GROUP BY b.partyid ) max_s ON p.partyid = max_s.partyid LEFT JOIN Smplandet b ON p.partyid = b.partyid LEFT JOIN Smplanmain a ON b.smplanid = a.smplanid AND a.smplandt = max_s.max_smplandt ORDER BY UPPER(p.partyname)
注意:如果同一Party有多条记录对应相同的最大Smplandt,此方案会返回多条结果,可根据需求补充筛选逻辑。
内容的提问来源于stack exchange,提问作者Ajoy Khaund
相关产品推荐
相关产品推荐

