SQL - 连接两个表并返回一行仅包含第二个表中的最新时间

时间:2016-01-11 17:10:32

标签: sql join greatest-n-per-group

我正在处理的表格包含有关其处理和详细信息约会的详细信息,分别命名为vwTreatmentPlans和vwAppointmentDetails。

我的目标是仅为每位患者代码返回一行。我希望它显示两列:来自vwTreatmentPlans表的患者代码和来自vwAppointmentDetails表的appointmentDateTimevalue。最重要的是,只要有多个约会行,我只想显示最新的约会细节,因此:

vA.appointmentDateTimevalue Desc

使用AND子句,每个PatientCode只返回一行,这就是我想要的。但是,两个表中的患者代码之间存在多对一关系的问题。

SELECT
    vT.PatientCode, MAX(vA.appointmentDateTimevalue)
FROM vwTreatmentPlans vT
    INNER JOIN vwAppointmentDetails vA ON vT.PatientCode = vA.patientcode
WHERE
    vT.PatientCode IN ( 123)
AND
    vT.[Current] = 1
AND
    vT.Accepted = 1
GROUP BY vT.PatientCode, vA.appointmentDateTimevalue
ORDER by vT.PatientCode, vA.appointmentDateTimevalue Desc

例如,一个患者代码返回以下输出:

PatientCode   appointmentDateTimevalue
123           2016-02-01 09:10:00.000
123           2016-01-07 09:15:00.000
123           2015-12-31 10:40:00.000

所以对于上面的例子,我想要这个输出:

PatientCode   appointmentDateTimevalue
123           2016-02-01 09:10:00.000

如果选择了多个患者代码,我希望:

PatientCode   appointmentDateTimevalue
123           2016-02-01 09:10:00.000
456           2016-04-11 15:45:00.000

我已经尝试过使用嵌套选择,有条款等等,坦白地说是一个线索。我真的很感激一些必须令人失望的简单帮助!

感谢。

5 个答案:

答案 0 :(得分:1)

为什么要按vA.appointmentDateTimevalue进行分组?你不需要这样做。 因此,您可以使用下一个查询获得结果集

SELECT
    vT.PatientCode, 
    MAX(vA.appointmentDateTimevalue) as max_date
FROM vwTreatmentPlans vT
    INNER JOIN vwAppointmentDetails vA ON vT.PatientCode = vA.patientcode
WHERE vT.[Current] = 1
         AND vT.Accepted = 1
GROUP BY vT.PatientCode
ORDER BY vt.patientCode

答案 1 :(得分:0)

通过对两者进行分组,你将杀死最大值

SELECT vT.PatientCode, MAX(vA.appointmentDateTimevalue)
  FROM vwTreatmentPlans vT
  JOIN vwAppointmentDetails vA 
        ON vT.PatientCode = vA.patientcode
       AND vT.PatientCode in (123)
       AND vT.[Current]   = 1
       AND vT.Accepted    = 1
 GROUP BY vT.PatientCode 
 ORDER by vT.PatientCode 

答案 2 :(得分:0)

PatientCode中提供了您显示的所有数据(appointmentDateTimevaluevwAppointmentDetails)。所以从那张桌子中选择。

要选择的记录的条件在表vwTreatmentPlans中,所以在where子句中有它。

select patientcode, max(appointmentdatetimevalue)
from vwappointmentdetails
where patientcode in
(
  select patientcode
  from vwtreatmentplans
  where patientcode in (123, ...)
  and current = 1
  and accepted = 1
)
group by patientcode;

无需加入此处。这使得查询非常易读且易于维护。令人失望的简单? : - )

答案 3 :(得分:0)

您已获得正确的答案,但我还有一件事要指出:

在回答我的其他答案时,你说:" ...我希望能够从vwTreatmentPlans表中选择额外的列"。但是该表中的一个患者代码可能有许多记录。如果您的标准(接受= 1和当前= 1)保证每个患者代码只能获得一条记录,那么没问题。但是,如果您仍然可以获得多条记录,则必须决定该表中的汇总数据(例如最小值或总和)。对于来自两个表的每个患者代码的许多记录,这可能变得复杂。例如,此查询会给您一个错误的总和(因为这些值会与匹配的vA记录的数量相乘):

SELECT
  vT.PatientCode, 
  MAX(vA.appointmentDateTimevalue) as max_date,
  SUM(vT.amount) as total_amount
FROM vwTreatmentPlans vT
INNER JOIN vwAppointmentDetails vA ON vT.PatientCode = vA.PatientCode
WHERE vT.Current = 1
  AND vT.Accepted = 1
GROUP BY vT.PatientCode
ORDER BY vt.PatientCode;

在这种情况下,您可能希望加入预先聚合的数据,而不是原始记录:

SELECT
  vT.PatientCode, 
  vA.max_date,
  vT.total_amount
FROM 
(
  SELECT PatientCode, SUM(amount) as total_amount
  FROM vwTreatmentPlans
  WHERE Current = 1
    AND Accepted = 1
  GROUP BY PatientCode
) vT
INNER JOIN 
(
  SELECT PatientCode, MAX(appointmentDateTimevalue) as max_date
  FROM vwAppointmentDetails
  GROUP BY PatientCode
) vA ON vT.PatientCode = vA.PatientCode
ORDER BY vt.PatientCode;

答案 4 :(得分:0)

@Thorsten Kettner

这实际上与我之后很快发生的情况相似,所以你的回复是完美的时间!最后我想出了下面的代码。它并不是特别优雅,因为我无法找到一种不必要地使用聚合函数的方法:

SELECT
    vT.PatientCode,
    vA.NextAppointmentDate,
    DefProvInis,
    UDAs
FROM
(
    SELECT PatientCode, MAX(TPNumber) as TPNumber, MIN(DefaultProviderInitials) as DefProvInis, MAX(UDAS) as UDAs
    FROM vwTreatmentPlans
    WHERE PatientCode in (
        1000001
        ,24001841
        ,20032285
        )
    AND [Current] = 1
    AND Accepted = 1
    GROUP BY PatientCode
) vT
INNER JOIN
(
    SELECT PatientCode, MAX(appointmentDateTimevalue) as NextAppointmentDate
    FROM vwAppointmentDetails
    GROUP BY PatientCode
) vA ON vA.PatientCode = vT.PatientCode
ORDER BY vA.PatientCode

我也需要知道列DefaultProviderInitials和UDAS。我认为我的结果是准确的,即使我正在为它们分配一个MIN()和MAX()(它似乎没有任何区别)尽管它很麻烦。