SQL:确定以给定频率发生活动

时间:2012-04-24 18:15:49

标签: sql oracle oracle10g

电子医疗记录(EMR)报告中确定活动以特定频率发生时的常见问题。在这种情况下,我需要确定在入院后每72小时写一张便条。

假设:

A                                       D
|-0-|-1-|-2-|-3-|-4-|-5-|-6-|-7-|-8-|-9-|
|---- 1 ----|---- 2 ----|---- 3 ----|-4-|

在第1,2和3期间需要至少有一个音符。因为4不是一个完整的72小时,所以它不需要音符。如果未能在第1,第2和第3期找到注释,将会失败。

数据:

(ENC):

ENC_ID  ADMITTED    DISCHARGED  PERIODS PASS_FAIL
4114221 06/15/09 18:30  06/24/09 15:40  3   ?

期间:TRUNC(CEIL((DISCHARGED - ADMITTED)/3))

'PASS_FAIL'列表示相遇是否有足够的音符数量和时间。

(注):

ENC_ID  NOTE_ID NOTE_TIME   PERIOD
4114221 1833764 06/17/09 08:42  1
4114221 1843613 06/18/09 08:14  1
4114221 1858159 06/18/09 20:15  2
4114221 1850948 06/18/09 20:15  2
4114221 1850912 06/18/09 20:18  2
4114221 1859315 06/19/09 18:35  2
4114221 1863982 06/20/09 10:29  2
4114221 1868895 06/21/09 22:00  3
4114221 1873539 06/22/09 15:42  3

期间:CEIL((NOTE_TIME - ADMITTED)/3)

有没有一种有效的方法来解决这个问题?

2 个答案:

答案 0 :(得分:0)

SELECT  e.*,
        CASE WHEN cnt = TRUNC(CEIL((discharged / admitted) / 3)) THEN 'pass' ELSE 'fail' END AS pass_fail
FROM    (
        SELECT  COUNT(*) AS cnt
        FROM    enc ei
        CROSS JOIN
                (
                SELECT  level AS period
                FROM    dual
                CONNECT BY
                        level <= 
                        (
                        SELECT  TRUNC(CEIL((discharged / admitted) / 3))
                        FROM    enc
                        WHERE   enc_id = :enc_id
                        )
                ) p
        WHERE   ei.enc_id = :enc_id
                AND EXISTS
                (
                SELECT  NULL
                FROM    note
                WHERE   enc_id = ei.enc_id
                        AND note_time >= ei.admitted + (p - 1) * 3
                        AND note_time < ei.admitted + p * 3
                )
        ) c
JOIN    enc e
ON      e.enc_id = :enc_id

答案 1 :(得分:0)

如果我正确地阅读了您的问题NOTE是一张包含所示数据的表格。

你真正关心的是第1期,第2期和第2期。每个enc_id的注释表中都有3个。

如果是这种情况,则表明应使用分析函数:

select e.enc_id, e.admitted, e.discharged, e.periods
     , decode( n.ct
             , 'pass'
             , 'fail' ) as pass_fail
  from enc e
  left outer join ( select distinct enc_id
                         , count(n.period) over ( partition by n.enc_id ) as ct
                      from note
                     where period in (1,2,3)
                           ) n
    on e.enc_id = n.enc_id

这将从enc_id中选择所有句点note,这是您要检查的句点。然后按enc_id计算它们。不同之处在于确保您在最终结果中每enc_id只获得一行。

如果您只想要那些值enc_id的{​​{1}},那么请将左外连接转为内连接。

如果note查询中没有period,则必须对完整查询而不是子查询执行不同操作,并检查每个note { {1}}在。

我对可怕的格式感到抱歉,但我想尝试将其放在页面上。

period

无论您的数据结构是什么,两种方式的好处都在于它们是简单的连接,一个索引唯一扫描(我假设note_id是唯一的)和一个索引范围扫描(在select distinct e.enc_id, e.admitted, e.discharged, e.periods , decode( count( distinct -- number of distinct periods case when n.note_time between e.admitted and e.admitted + 3 then 1 when n.note_time between e.admitted and e.admitted + 6 then 2 when n.note_time between e.admitted and e.admitted + 9 then 3 end ) -- per enc_id from note over ( partition by n.enc_id ) -- if it-s 3 then pass , 3, 'pass' -- else fail. , 'fail' ) as pass_fail from enc e left outer join note n on e.enc_id = n.enc_id 上)