2013-04-17 72 views
0

我试图找到在另一个日期/时间值的24小时内发生的第一个日期/时间值。SQL:另一日期/时间的24小时内的最小日期/时间值

ENCOUNTER表:

ENC_ID ADMSN_TIME   DISCH_TIME 
16755387 03/19/13 11:10:00 03/22/13 12:55:00 

PROBLEM_LIST表:

ENC_ID  REVIEWED_TIME  USER_ID 
16755387 03/19/13 13:02:00 FOOBAR 
16755387 03/19/13 13:03:00 FOOBAR 
16755387 03/20/13 07:52:00 FOOBAR 
16755387 03/22/13 08:35:00 FOOBAR 
16755387 03/22/13 08:35:00 FOOBAR 
16755387 03/22/13 08:35:00 FOOBAR 

所需的结果集:

ENC_ID ADMSN_TIME   ADMSN_REVIEW_TIME ADMSN_REVIEWER DISCH_REVIEW_TIME DISCH_REVIEWER 
16755387 03/19/13 11:10:00 03/19/13 13:02:00 FOOBAR   03/22/13 08:35:00 FOOBAR 

规则:

  1. ABS(REVIEWED_TIME - ADMSN_TIME)< = 1个
  2. ABS(REVIEWED_TIME - DISCH_TIME)< = 1
  3. 可能不存在对应于入院时,或放电的审查时间,或两者

我的第一尝试:

SELECT E.ENC_ID, 

     E.ADMSN_TIME, 
     R0.REVIEWED_TIME ADMSN_REVIEWED_TIME, 
     R0.USER_ID ADMSN_REVIEWER, 

     E.DISCH_TIME, 
     R1.REVIEWED_TIME DISCH_REVIEWED_TIME, 
     R1.USER_ID DISCH_REVIEWER 

FROM ENCOUNTER E 
INNER JOIN PROBLEM_LIST R0 ON HE.ENC_ID=R0.ENC_ID 
    and r0.REVIEWED_TIME = (
    SELECT MIN(REVIEWED_TIME) 
    FROM PROBLEM_LIST 
    WHERE ENC_ID=E.ENC_ID 
    AND  ABS(REVIEWED_TIME - ADMSN_TIME)<=1  
    ) 
INNER JOIN PROBLEM_LIST R1 ON E.ENC_ID=R1.ENC_ID 
    and r1.REVIEWED_TIME = (
    SELECT MIN(REVIEWED_TIME) 
    FROM PROBLEM_LIST 
    WHERE ENC_ID=E.ENC_ID 
    AND  ABS(REVIEWED_TIME - DISCH_TIME)<=1  
    ) 

问题:

  • 没有异体w缺少评论(规则#3);用“OUTER JOIN”生成语法错误
  • 不消除重复PROBLEM_LIST记录

有没有一种方法,使这项工作?

**编辑**

SELECT DISTINCT ENC_ID, 
     E.ADMSN_TIME, 
     FIRST_VALUE(R0.REVIEWED_TIME) OVER (PARTITION BY R0.ENC_ID ORDER BY R0.REVIEWED_TIME) ADMSN_REVIEWED_TIME, 
     FIRST_VALUE(R0.USER_ID) OVER (PARTITION BY R0.ENC_ID ORDER BY R0.REVIEWED_TIME) ADMSN_REVIEWED_BY, 
     E.DISCH_TIME, 
     FIRST_VALUE(R1.REVIEWED_TIME) OVER (PARTITION BY R1.ENC_ID ORDER BY R1.REVIEWED_TIME) DISCH_REVIEWED_TIME 
     ,FIRST_VALUE(R1.USER_ID) OVER (PARTITION BY R1.ENC_ID ORDER BY R1.REVIEWED_TIME) DISCH_REVIEWED_BY 

FROM ENCOUNTER E 
LEFT JOIN PROBLEM_LIST R0 ON E.ENC_ID=R0.ENC_ID 
    AND ABS(r0.REVIEWED_TIME - ADMSN_TIME)<=1 
LEFT OUTER JOIN PROBLEM_LIST R1 ON E.ENC_ID=R1.ENC_ID 
    AND ABS(R1.REVIEWED_TIME - DISCH_TIME)<=1 

根据需要,但DISTINCT条款似乎并不是最佳的,这个方法工作。有没有更高效的查询?

+0

你说你想要的最低,这表明我应该在你的查询某处查看min()函数。 –

+0

@DanBracuk,子选择中有一个“MIN”。'SELECT MIN(REVIEWED_TIME)...' – craig

回答

0

我想出了下面,它适用于几个测试。使用LEAD分析功能和一个UNION。

SELECT enc_id, 
     admsn_time, 
     CASE 
      WHEN TO_CHAR (admsn_time, 'DDMMYYYY') = 
        TO_CHAR (admsn_review_time, 'DDMMYYYY') 
      THEN 
      admsn_review_time 
      ELSE 
      NULL 
     END 
      AS admsn_review_time, 
     CASE 
      WHEN TO_CHAR (admsn_time, 'DDMMYYYY') = 
        TO_CHAR (admsn_review_time, 'DDMMYYYY') 
      THEN 
      admsn_user 
      ELSE 
      NULL 
     END 
      AS admsn_review_user, 
     disch_time, 
     CASE 
      WHEN TO_CHAR (disch_time, 'DDMMYYYY') = 
        TO_CHAR (disch_review_time, 'DDMMYYYY') 
      THEN 
      disch_review_time 
      ELSE 
      NULL 
     END 
      AS disch_review_time, 
     CASE 
      WHEN TO_CHAR (disch_time, 'DDMMYYYY') = 
        TO_CHAR (disch_review_time, 'DDMMYYYY') 
      THEN 
      disch_user 
      ELSE 
      NULL 
     END 
      AS disch_review_user 
    FROM (SELECT enc_id, 
       admsn_time, 
       LEAD (admsn_time, 1) 
        OVER (PARTITION BY enc_id ORDER BY admsn_time) 
        admsn_review_time, 
       LEAD (user_id, 1) 
        OVER (PARTITION BY enc_id ORDER BY admsn_time) 
        admsn_user, 
       disch_time, 
       LEAD (disch_time, 1) 
        OVER (PARTITION BY enc_id ORDER BY disch_time) 
        disch_review_time, 
       LEAD (user_id, 1) 
        OVER (PARTITION BY enc_id ORDER BY disch_time) 
        disch_user, 
       ch 
      FROM (SELECT e.enc_id, 
         admsn_time, 
         disch_time, 
         'E' AS ch, 
         NULL AS user_id 
        FROM encounter e 
       UNION 
       SELECT enc_id, 
         reviewed_time, 
         reviewed_time, 
         'P', 
         user_id 
        FROM problem_list pl)) 
WHERE ch = 'E'; 
0

不知道这将是比任何你的整体第二种方案更有效,但它避免了distinct和两个加入到problem_list。还是觉得过于复杂的 - 做一个unpivot后跟一个pivot似乎是一个黑客 - 但它的部分原因是我自己的娱乐:

select enc_id, admsn_time, admsn_review_time, admsn_reviewer, 
    disch_time, disch_review_time, disch_reviewer 
from (
    select enc_id, admsn_time, disch_time, user_id, reviewed_time, review_type 
    from (
     select * 
     from (
      select e.enc_id, e.admsn_time, e.disch_time, 
       pl.user_id, pl.reviewed_time, 
       row_number() over (partition by e.enc_id 
        order by abs(pl.reviewed_time - e.admsn_time)) 
         as admsn_reviewed_rn, 
       row_number() over (partition by e.enc_id 
        order by abs(pl.reviewed_time - e.disch_time)) 
         as disch_reviewed_rn 
      from encounter e 
      left join problem_list pl on pl.enc_id = e.enc_id 
     ) 
     unpivot (rn for review_type in (admsn_reviewed_rn as 'ADMSN', 
      disch_reviewed_rn as 'DISCH')) 
    ) 
    where rn = 1 
    and (abs(reviewed_time - admsn_time) <= 1 
     or abs(reviewed_time - disch_time) <= 1) 
) 
pivot (min(reviewed_time) as review_time, min(user_id) as reviewer 
for review_type in ('ADMSN' as admsn, 'DISCH' as disch)) 
/

其中给出:

ENC_ID ADMSN_TIME   ADMSN_REVIEW_TIME ADMSN_ DISCH_TIME   DISCH_REVIEW_TIME DISCH_ 
---------- ------------------- ------------------- ------ ------------------- ------------------- ------ 
    16755387 03/19/0013 11:10:00 03/19/0013 13:02:00 FOOBAR 03/22/0013 12:55:00 03/22/0013 08:35:00 FOOBAR 
0

你的基本的问题是如何找到T时间以后第一次受到约束。从这里开始,

SELECT E.ENC_ID, 
     E.ADMSN_TIME, 
     min(REVIEWED_TIME) as ADMSN_REVIEWED_TIME, 
FROM ENCOUNTER as E 
JOIN PROBLEM_LIST as P 
ON  E.ENC_ID = P.ENC_ID 
AND  ADMSN_TIME < REVIEWED_TIME 
AND  REVIEWED_TIME <= ADMSN_TIME + 1 
GROUP BY E.ENC_ID, E.ADMSN_TIME 

加入到其他任何你需要的东西。

相关问题