我正在尝试查找在另一个日期/时间值的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
规则:
我的第一次尝试:
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
)
的问题:
有没有办法让这项工作?
**编辑**
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 :(得分: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';
答案 1 :(得分: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
答案 2 :(得分: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
将其加入到您需要的任何其他内容中。