2012-04-24 3 views
2

특정 빈도로 활동이 발생했음을 확인하는 전자 의료 기록 (EMR)보고의 일반적인 문제입니다. 이 상황에서 입학 후 72 시간마다 메모를 작성해야한다고 결정해야합니다.SQL : 특정 빈도로 활동이 발생했는지 확인하십시오.

을 감안할 때 :

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

이 메모를 필요로하지 않습니다, 4 전체 72 시간 동안이 아니기 때문에 하나 이상의 기간 1, 2시 참고 및 3이있을 필요가있다 . 1, 2, 3기에 메모를 찾지 못하면 FAIL이됩니다.

데이터 :

(ENC) :

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

PERIODS : 만남은 노트의 적절한 수와 타이밍이 있다면 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)

이 문제를 해결하기위한 효율적인 방법이 있나요?

답변

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 
0

나는 당신의 질문을 읽고 있어요 경우 제대로 NOTE는 표시된 데이터가있는 테이블입니다.

여러분이 정말로 신경 쓰는 것은 각각 enc_id의 notes 테이블에 기간 1, 2 & 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_idnote에서 검사 할 것들있는을 선택합니다. 그런 다음 enc_id에 따라 계산합니다. 구별은 최종 결과에서 enc_id 당 한 행만 확보 할 수 있도록합니다.

note의 값을 가진 이들 enc_id 만 원하는 경우 왼쪽 외부 조인을 내부 조인으로 바꿉니다.

period하는 경우입니다 표시된대로되지는 note 쿼리에서, 당신은 오히려 하위 쿼리에 비해 전체 쿼리에 별개의 작업을 수행하고 각 note_id가에있는 period 확인해야합니다.

미안 해요 끔찍한 형식화에 대해서 그러나 나는 페이지에 그것을 맞추려고했다.

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 

두 가지의 장점들이 단순 조인 것을있는 무엇이든 데이터 구조를 하나의 인덱스의 고유 스캔 (나는 enc.end_id이 고유 있으리라 믿고있어) 및 (note)에 하나의 인덱스 범위 스캔.

+0

NOTE는 테이블 그룹입니다. PERIOD 열은 노트가 '충족'하는 기간 (말하자면)을보다 쉽게 ​​결정할 수있게 해주는 계산입니다. PERIODS의 수는 ENC의 ADMITTED 및 DISCHARED 날짜 (물론 최소 1)에 전적으로 달려 있습니다. 나는 ENCs를 10 년 동안 보았다. 다시 말해, 솔루션은 ENC의 지속 기간 (즉, # PERIODS)에 적응해야합니다. – craig

관련 문제