使用Report Builder 3.0 for SQL Server 08 R2获取单条最大日期结果失败求助
搞定每个患者一行返回双表最大日期的问题
嘿,我懂你现在的困扰:用Report Builder 3.0查SQL Server 2008 R2,本来想每个患者一行,同时拿到PatAdmissions里的最晚出院日期和PatVisitPayable里的最晚联系日期,结果跑出来4行而不是1行。这问题根源很明确——你直接关联三张表的时候,每个患者可能有多条住院记录或付费记录,关联后产生了笛卡尔积,把所有可能的组合都列出来了。
下面给你两种靠谱的解决办法,都是先聚合出每个患者的最大日期,再关联主表,保证每个患者只返回一行:
方法一:子查询聚合(最直接高效)
先分别用子查询算出每个患者的最大出院日期和最大联系日期,再和Patient表关联,这样每个子查询都只会给每个患者返回一行数据:
SELECT p.PatientID, p.PatientLastName, p.PatientFirstName, pa.MaxDischargeDate, pvp.MaxContactDate FROM BTI.Patient p LEFT JOIN ( -- 聚合每个患者的最晚出院日期 SELECT PatientID, MAX(DischargeDate) AS MaxDischargeDate FROM BTI.PatAdmissions GROUP BY PatientID ) pa ON p.PatientID = pa.PatientID LEFT JOIN ( -- 聚合每个患者的最晚联系日期 SELECT PatientID, MAX(ContactDate) AS MaxContactDate FROM BTI.PatVisitPayable GROUP BY PatientID ) pvp ON p.PatientID = pvp.PatientID
小提示:
- 用
LEFT JOIN是为了保证即使某个患者没有住院记录或者付费记录,也能出现在结果里(对应的日期会显示NULL)。如果你的业务要求只保留同时有两种记录的患者,把LEFT JOIN改成INNER JOIN就行。
方法二:窗口函数(灵活备选)
如果你更习惯用窗口函数,也可以用ROW_NUMBER()给每个患者的记录按日期排序,只取最新的那一条:
WITH RankedAdmissions AS ( SELECT PatientID, DischargeDate, -- 按患者分组,日期倒序排名,最新的排第1 ROW_NUMBER() OVER (PARTITION BY PatientID ORDER BY DischargeDate DESC) AS rn FROM BTI.PatAdmissions ), RankedVisitPayable AS ( SELECT PatientID, ContactDate, ROW_NUMBER() OVER (PARTITION BY PatientID ORDER BY ContactDate DESC) AS rn FROM BTI.PatVisitPayable ) SELECT p.PatientID, p.PatientLastName, p.PatientFirstName, ra.DischargeDate AS MaxDischargeDate, rvp.ContactDate AS MaxContactDate FROM BTI.Patient p LEFT JOIN RankedAdmissions ra ON p.PatientID = ra.PatientID AND ra.rn = 1 LEFT JOIN RankedVisitPayable rvp ON p.PatientID = rvp.PatientID AND rvp.rn = 1
注意点:
- 一定要确保
PatientID是每个患者的唯一标识,这样聚合和关联才不会出错。 - 如果某个患者有多个相同的最大日期(比如同一天多次出院),两种方法都会只返回一个日期值,完全符合你要一行数据的需求。
内容的提问来源于stack exchange,提问作者anddon
相关产品推荐
相关产品推荐

