我无法从Oracle数据库获取我想要的数据。任何帮助将不胜感激。这是我的表格的样本:
Table: Vaccinations
Patient_ID | Shot_ID | Series | Date_Taken
-------------------------------------------
123 | 5 | B | 8/1/2011
123 | 5 | 3 | 2/1/2011
123 | 5 | 2 | 1/10/2011
123 | 5 | 1 | 1/1/2011
456 | 3 | 2 | 1/10/2011
456 | 3 | 1 | 1/1/2011
123 | 5 | 2 | 10/1/2010
123 | 5 | 1 | 9/1/2010
系列列指示针对特定Shot_ID
管理的镜头。 “B”表示给予助推器,“2”表示第二个,“1”表示第一个,依此类推,但“3”表示最大值,然后是助推器。对于特定类型的镜头(Shot_ID
),我正在尝试为患者抓取所有最新系列的镜头。例如,我想抓住患者123的Shot_ID
= 5的最新系列镜头,所以我想在这种情况下返回前四个记录(所有列应该在这些行中返回)。最后两个应该省略,因为2011年1月1日开始了一系列新镜头。无论如何,我有一个algortihm,但我在编写查询时遇到了麻烦。它会是这样的:
获取患者123的最长日期shot_id = 5
。返回行并查看其系列(在本例中为“B”)。
从最大日期获取下一个最低日期并查看其系列(在本例中为“3”)。如果系列介于1和B之间,则返回该行。如果不存在其他记录,则结束查询。
从第2步获取下一个最低日期并查看其系列(在本例中为“2”)。如果系列小于步骤2中的系列,则返回该行。否则,请结束查询。
你继续重复这些步骤,直到你到达series = 1
,这将返回或直到你达到一个大于或等于当前系列的系列,这个系列不会被返回。因此,输出应如下所示:
123 | 5 | B | 8/1/2011
123 | 5 | 3 | 2/1/2011
123 | 5 | 2 | 1/10/2011
123 | 5 | 1 | 1/1/2011
这个查询似乎相当复杂,但也许我只是在思考它。谢谢你们的时间。
答案 0 :(得分:0)
我愿意:
SELECT v1.* FROM vaccinations v1
LEFT JOIN vaccinations v2
ON v2.patient_id = v1.patient_id AND v2.shot_id = v1.shot_id
AND v2.series = '1' AND v2.date_taken > v1.date_taken
WHERE v2.series IS NULL
AND v1.patient_id = '123'
AND v1.shot_id = '5';
左连接查找更近期的新镜头的开始。如果它没有返回任何行(IS NULL
),那么这是最新的镜头。这相当于:
SELECT * FROM vaccinations v1
WHERE patient_id = '123'
AND shot_id = '5'
AND NOT EXISTS (SELECT NULL FROM vaccinations v2
WHERE v2.patient_id = v1.patient_id AND v2.shot_id = v1.shot_id
AND v2.series = '1' AND v2.date_taken > v1.date_taken
);
如果最新系列不一定以1开头,那么:
WITH all_series AS
( SELECT rownum rn, series, date_taken
FROM vaccinations
WHERE patient_id = '123' AND shot_id = '5' AND series <> 'B'
ORDER BY date_taken ASC
)
, last_series_beginning AS
( SELECT MAX(as1.date_taken) x
FROM all_series as1
LEFT JOIN all_series as2 -- we need to keep first row in as1
ON as2.rn = as1.rn - 1
WHERE as1.series < as2.series
OR as1.rn = 1
)
SELECT * FROM vaccinations
WHERE patient_id = '123' AND shot_id = '5'
AND date_taken > ( SELECT x FROM last_series_beginning );
答案 1 :(得分:0)
我采取双管齐下的方法。获取最新的“系列1”镜头,然后获得所有后续系列。
SELECT Patient_ID, Shot_ID, Series, Date_Taken
FROM Vaccinations v
WHERE Patient_ID = 123
AND Shot_ID = 5
AND Date_Taken >= (SELECT MAX(Date_Taken)
FROM Vaccinations v
WHERE Patine_ID = 123
AND Shot_ID = 5
AND Series = 1)
答案 2 :(得分:0)
select * from vaccinations as v
inner join (
select a.series , max(a.date_taken) as max_date
from vaccinations as a, vaccinations as b
where a.series = b.series
and not exists (
select * from vaccinations as c where c.series = a.series
and c.date_taken between a.date_taken and b.date_taken)) as m
on v.date_taken >= m.max_date and patient_id = 123 and shot_id = 5
不存在 - 保持重复序列对开始(或停止)...但如果只有1个系列存在问题
答案 3 :(得分:0)
此查询会忽略任何具有相同或更低系列的新镜头(对于相同的Patient_ID和Shot_ID):
select s.*
from Shot s
inner join (
select Patient_ID, Shot_ID, max(Date_Taken) as MaxDate
from Shot
group by Patient_ID, Shot_ID
) sm on s.Patient_ID = sm.Patient_ID and s.Shot_ID = sm.Shot_ID
inner join Shot s2 on sm.Patient_ID = s2.Patient_ID and sm.Shot_ID = s2.Shot_ID and sm.MaxDate = s2.Date_Taken
where (s.Date_Taken = sm.MaxDate
or (
case when s.Series = 'B' then 4 else s.Series end < case when s2.Series = 'B' then 4 else s2.Series end
and not exists (
select 1
from Shot
where Date_Taken > s.Date_Taken
and Shot_id = s.Shot_ID
and case when Series = 'B' then 4 else Series end <= case when s.Series = 'B' then 4 else s.Series end
)
)
)
and s.Patient_ID = 123
答案 4 :(得分:0)
`select A.patient_id , A.shot_id , A.series , max(date_taken)
From cs_study A
inner join
(
select max(shot_id) max_shotid, patient_id from cs_study
group by patient_id
) b
on A.shot_id =B.max_shotid
and a.patient_id = B.patient_id
group by A.patient_id , A.shot_id , A.series`