【发布时间】:2010-12-16 08:44:56
【问题描述】:
我有一张患者表:
PatientId Admitted
--------- ---------------
1 d/m/yy hh:mm:ss
2 d/m/yy hh:mm:ss
3 d/m/yy hh:mm:ss
我有一个 PatientMeasurement 表(0 到多个):
PatientId MeasurementId Recorded Value
--------- ------------- --------------- -----
1 A d/h/yy hh:mm:ss 100
1 A d/h/yy hh:mm:ss 200
1 A d/h/yy hh:mm:ss 300
2 A d/h/yy hh:mm:ss 10
2 A d/h/yy hh:mm:ss 20
1 B d/h/yy hh:mm:ss 1
1 B d/h/yy hh:mm:ss 2
我正在尝试创建类似于以下内容的结果集:
PatientId Numerator Denominator
--------- -------- -----------
1 1 1
2 1 1
3 0 1
本质上,如果患者 A 测量值至少有一个值,B 测量值至少有一个值,则患者的分子将是 1。在此示例中,患者 1 具有 3 个 A 测量值和 2 个 B 测量值,因此分子为1. 患者 2 有 2 个 A 测量值,但没有 B 测量值,因此分子为 0。患者既没有 A 测量值也没有 B 测量值,因此分子为 0。
到目前为止我的查询是:
SELECT PatientId, CASE WHEN a.cnt+b.cnt>2 THEN 1 ELSE 0 END Numerator, 1 Denominator
FROM patient p
LEFT OUTER JOIN (
SELECT PatientId, count(*) cnt
FROM PatientMeasurement pm
WHERE MeasurementId='A'
--AND Recorded <= dateadd(hh, 12, Admitted)
GROUP BY PatientId
) a ON p.PatientId=a.PatientId
LEFT OUTER JOIN (
SELECT PatientId, count(*) cnt
FROM PatientMeasurement pm
WHERE MeasurementId='B'
--AND Recorded <= dateadd(hh, 12, Admitted)
GROUP BY PatientId
) b ON p.PatientId=b.PatientId
只要我不包含相关的日期限制(Recorded
这迫使我将 SQL 重写为:
SELECT PatientId, CASE WHEN v.a+v.b>2 THEN 1 ELSE 0 END Numerator, 1 Denominator
FROM (
SELECT PatientId,
(
SELECT PatientId, count(*) cnt
FROM PatientMeasurement pm
WHERE PatientId=p.PatientId
AND MeasurementId='A'
AND Recorded <= dateadd(hh, 12, Admitted)
GROUP BY PatientId
) a,
(
SELECT PatientId, count(*) cnt
FROM PatientMeasurement pm
WHERE PatientId=p.PatientId
AND MeasurementId='B'
AND Recorded <= dateadd(hh, 12, Admitted)
GROUP BY PatientId
) b
FROM Patient p
) v
我的问题:有没有更好、更有效的方法来做到这一点?
感谢您的宝贵时间。
【问题讨论】:
标签: sql sql-server syntax derived-table inline-view