Sql 在第一个最高分数之后找到最低分数
我正在寻找一个SQL查询 表1:源表 表2:结果表 附在病人桌上。这里我想找到每个患者的最高得分、最高得分日期、最低得分和最低得分日期。棘手的是,如果患者在两个不同的日期(2018年5月10日和2020年4月8日)获得相同的最高分数(此处为9),我们需要最早获得最高分数(2018年5月10日)。同样,如果患者在两个不同的日期(2019年3月1日和2020年4月2日)有相同的最低分数(此处为6),我们应采用最新的最低分数(2020年4月2日) 表1:源表包含单个患者的所有得分。患者ID是该表的主键。我想要一个类似于表2的结果表 我试过这个Sql 在第一个最高分数之后找到最低分数,sql,sql-server,Sql,Sql Server,我正在寻找一个SQL查询 表1:源表 表2:结果表 附在病人桌上。这里我想找到每个患者的最高得分、最高得分日期、最低得分和最低得分日期。棘手的是,如果患者在两个不同的日期(2018年5月10日和2020年4月8日)获得相同的最高分数(此处为9),我们需要最早获得最高分数(2018年5月10日)。同样,如果患者在两个不同的日期(2019年3月1日和2020年4月2日)有相同的最低分数(此处为6),我们应采用最新的最低分数(2020年4月2日) 表1:源表包含单个患者的所有得分。患者ID是该表的
SELECT distinct
pat.PAT_NAME 'Patient Name'
, pat.PAT_ID
, CAST(pat.CONTACT_DATE AS DATE) 'Service Date'
, pat.MEAS_VALUE 'Score'
, [Row Number] = rank() OVER (PARTITION BY pat.PAT_ID ORDER BY CAST(pat.MEAS_VALUE AS int) DESC, CONTACT_DATE asc)
FROM Patient pat
WHERE pat.PAT_ID = 'A112233'
但是这个代码可以显示最高或最低的分数。但它并不满足我的所有要求。如果表t中有以下列:PatientName、PatientID、ServiceDate、Score。大概是这样的:
;with high_low_cte(PatientID, high_rn, low_rn) as(
select
PatientID,
row_number() over (partition by PatientID order by Score, ServiceDate asc),
row_number() over (partition by PatientID order by Score, ServiceDate desc)
from
t)
select * from high_low_cte where high_rn=1 and low_rn=1;
更新问题后:
;with high_low_cte([Patient Name], PAT_ID, [Service Date], Score, high_rn, low_rn) as (
SELECT distinct
pat.PAT_NAME 'Patient Name'
,pat.PAT_ID
,CAST(pat.CONTACT_DATE AS DATE) 'Service Date'
,pat.MEAS_VALUE 'Score'
,high_rn=row_number() OVER (PARTITION BY pat.PAT_ID ORDER BY CAST(pat.MEAS_VALUE AS int) DESC, CONTACT_DATE asc)
,low_rn=row_number() OVER (PARTITION BY pat.PAT_ID ORDER BY CAST(pat.MEAS_VALUE AS int) asc, CONTACT_DATE asc)
FROM
Patient pat
WHERE
pat.PAT_ID='A112233')
select hld1.*, hld2.Score [Low_Score], hld2.[Service Date] [Low Service Date]
from high_low_cte hld1 join high_low_cte hld2 on hld1.PAT_ID=hld2.PAT_ID
where
hld1.high_rn=1
and hld2.low_rn=1;
您可以将条件聚合与
行数()一起使用:
我还没有测试过,但也许像这样的东西可以完成这项工作:
select x.PatientName, x.PatientId,
case when x.HSD=1 then 'Highest' else 'Lowest' as ScoreType,
Score, ScoreDate
from (
select
p.PAT_NAME as PatientName,
p.PAT_ID as PatientId,
p.MEAS_VALUE as Score,
p.CONTACT_DATE as ScoreDate,
row_number() over (partition by p.PatientId order by p.MEAS_VALUE desc, p.CONTACT_DATE desc) as HSD,
row_number() over (partition by p.PatientId order by p.MEAS_VALUE asc, p.CONTACT_DATE asc) as LSD
from Patient p
) x
where
x.HighestScore=1 or
x.LowestScoreDate=1
你应该收到两行。为了获得预期的输出,您需要对数据进行透视。首先,获得最高和最低分数,然后找到发生的日期
;with scores as ( -- get highest/lowest score per patientId
select patientID, max(score) hScore, min(score) lScore
from table
group by patientID
), dates as (
-- get first date a patient had the highest score
select patientID, min(ServiceDate) dateHScore, score
from table t
inner join scores s on s.patientid = t.patientid and s.hScore= t.score
group by patientID, score
union all
-- get the last date a patient had the lowest score
select patientID, max(ServiceDate) dateLScore, score
from table t
inner join scores s on s.patientid = t.patientid and s.lScore = t.score
group by patientID, score
)
select t.patientName, scores.*
from table t
inner join scores s on s.patientid= t.patientid
如果您希望在同一行的不同列上获得最高/最低分数,只需拆分第二个cte,并将它们适当地连接到select1中。请将数据显示为格式化文本,而不是图像(理想情况下为DDL/DML语句)。2.请告诉我们您的尝试-因此不是代码编写服务。谢谢Steve。我尝试过这种方法,但我想根据某些条件找出最高和最低分数。这里我想找到每个患者的最高得分、最高得分日期、最低得分和最低得分日期。棘手的是,如果患者在两个不同的日期(2018年5月10日和2020年4月8日)获得相同的最高分数(此处为9),我们需要最早获得最高分数(2018年5月10日)。同样,如果患者在两个不同的日期(2019年3月1日和2020年4月2日)有相同的最低分数(此处为6),我们应该采用最新的最低分数(2020年4月2日)。这很有效。我只做了一件小事,就是让desc在Low_rn中指定联系日期,以查找最新的Low-score。除此之外,它是完美的。还要感谢每一位回答问题的人……如果可以在一次访问中查询同一个表3次,这通常不是一个好主意。
;with scores as ( -- get highest/lowest score per patientId
select patientID, max(score) hScore, min(score) lScore
from table
group by patientID
), dates as (
-- get first date a patient had the highest score
select patientID, min(ServiceDate) dateHScore, score
from table t
inner join scores s on s.patientid = t.patientid and s.hScore= t.score
group by patientID, score
union all
-- get the last date a patient had the lowest score
select patientID, max(ServiceDate) dateLScore, score
from table t
inner join scores s on s.patientid = t.patientid and s.lScore = t.score
group by patientID, score
)
select t.patientName, scores.*
from table t
inner join scores s on s.patientid= t.patientid