0

我正在尝试查找在另一个日期/时间值的 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      
    )

问题:

  • 不允许漏检(规则#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子句似乎不是最优的。有没有更高效的查询?

4

3 回答 3

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';
于 2013-04-17T20:53:00.627 回答
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

将其加入您需要的任何其他内容。

于 2013-04-18T07:27:59.980 回答
0

不确定这是否会比您的第二个解决方案更有效,但它避免了distinct和两个连接到problem_list. 仍然感觉过于复杂 - 做 aunpivot后跟 apivot似乎是一种黑客行为 - 但这部分是为了我自己的乐趣:

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
于 2013-04-17T20:54:53.523 回答