问题:
如何从
max(d1_10.dstartdate)
中小于每个 xpid
的 d1_10
(最新疗程日期)的日期选择中为每个 xpid
(患者 ID)选择 max(d8.start_date)
(最新单位转移日期) )?
信息:
表格:
d0
患者列表,每个 xpid
(患者)包含 1 行
d0.xpid
独特的患者 ID d8
会话表,每个xpid
每个会话包含 1 行
d8.xpid
患者 ID d8.start_date
课程开始日期d1_10
单位传输表,每个 xpid
每次传输包含 1 行
d1_10.dstartdate
转账日期问题:
目前我有一个查询列出了
xpid
、max(d8.start_date)
和 max(d1_10.startdate)
。但是,max(d1_10.startdate)
不一定小于max(d8.start_date)
目标是获得所有患者的列表、他们的最近一次就诊日期以及他们的最新转移日期仍早于他们的就诊日期。目前转移日期与会话日期无关。
我尝试过嵌套连接查询,但无法弄清楚调用变量的范围。
进度:
这是我拥有的最接近的运行代码:
select distinct
d0.xpid,
sessions.max_date,
units.max_unit
from d0
left join
(
select xpid, max(start_date) as max_date
from d8
group by xpid
) as sessions on sessions.xpid = d0.xpid
left join
(
select xpid, max(d1_10.dstartdate) as max_unit
from d1_10
group by xpid
) as units on units.xpid = d0.xpid
输出片段:
注意
null
值,这些很好,我们想要这些。我们希望 d0
中的每个患者都有一行输出,无论他们在 d8
或 d1_10
中的行如何。
提前致谢,如果我能提供更清晰的信息,请告诉我。
附加信息:
尝试按照塞巴斯蒂安的建议添加
and units.max_unit <= sessions.max_date
。它很接近,但我们不是用 max_unit <= max_date
来限制,而是在取最大值之前需要所有 d1_10.dstartdate <= sessions.max_date
。我们希望它在获取最大值之前限制它选择的池 units.max_unit
。@Sebastian,假设
xpid = 2500
在d1_10
中有3行,其中d1_10.dstartdate in ('01-jan-2017', '01-feb-2017', '01-mar-2017')
和max(d8.start_date) = '10-feb-2017'
。
根据您的建议,
max_unit is null
,因为max(d1_10.dstartdate) = '01-mar-2017'
,但是'01-mar-2017 > '10-feb-2017'
。
在取最大值之前我们需要限制
d1_10.dstartdate <= max(d8.start_date)
。所需值应为 max_unit = '01-feb-2017'
,因为这是该患者的最大转移日期,小于该患者的最大疗程日期。如果我能更好地清理它,请告诉我。添加
AND d1_10.max_unit < sessions.max_date
第二个左连接的 on 子句就足够了。
编辑完成后,请尝试一下:
SELECT d0.xpid,
d8.[start_date],
d1_10.dstartdate
FROM d0
LEFT JOIN d8
ON d0.xpid = d8.xpid
LEFT JOIN d1_10
ON d1_10.xpid = d8.xpid
AND d1_10.dstartdate = (
SELECT MAX(u1.dstartdate)
FROM d1_10 as u1
WHERE d8.xpid = u1.xpid
AND u1.dstartdate <= d8.start_date
GROUP BY u1.xpid
)
这是一个非常老的问题,但我有一个非常相似的问题,不得不敲了几个小时才能解决它,如果我正确理解需要做什么,这应该能够为发现这个问题的任何人提供帮助谷歌提问。
假设我们有下一个数据
患者
patient
patient1
patient2
patient3
会议
patient,session_date
patient1,2024-04-01
patient1,2024-05-01
patient2,2024-04-01
单位转让
patient,transfer_date
patient1,2024-03-15
patient1,2024-04-02
patient1,2024-04-15
patient2,2024-04-15
现在,让我们暂时忘记表患者,我们将在最后使用它来获取所有患者的列表,无论他们的会话或左连接的转移,但现在让我们专注于会话和单位转移
第一件事是我们必须得到一个笛卡尔乘积,以便我们稍后可以过滤数据
patient,session_date,transfer_date
patient1,2024-04-01,2024-03-15
patient1,2024-04-01,2024-04-02
patient1,2024-04-01,2024-04-15
patient1,2024-05-01,2024-03-15
patient1,2024-05-01,2024-04-02
patient1,2024-05-01,2024-04-15
patient2,2024-05-01,2024-04-15
此时我们可以使用 Sebastian 的建议并过滤早于传输日期的会话
patient,session_date,transfer_date
patient1,2024-04-01,2024-03-15
patient1,2024-05-01,2024-03-15
patient1,2024-05-01,2024-04-02
patient1,2024-05-01,2024-04-15
patient2,2024-05-01,2024-04-15
现在唯一剩下的就是在下一次疗程之前获得最新的单位转移,因为我们可以对患者和疗程进行分组,并获得最大转移日期
patient,session_date,transfer_date
patient1,2024-04-01,2024-03-15
patient1,2024-05-01,2024-04-15
patient2,2024-05-01,2024-04-15
现在,如果您仍然需要获取所有患者,您可以进行左连接并找到不在前一个子集中的患者:
patient,patient_1,session_date,transfer_date
patient1,patient1,2024-04-01,2024-03-15
patient1,patient1,2024-05-01,2024-04-15
patient2,patient2,2024-05-01,2024-04-15
patient3,,,
这是我使用的 SQL
WITH patients AS (SELECT 'patient1' AS patient, UNION ALL SELECT 'patient2' UNION ALL SELECT 'patient3'),
sessions AS (SELECT 'patient1' AS patient, '2024-04-01' AS session_date
UNION ALL
SELECT 'patient1', '2024-05-01'
UNION ALL
SELECT 'patient2', '2024-05-01'),
unit_transfers AS (SELECT 'patient1' AS patient, '2024-03-15' AS transfer_date
UNION ALL
SELECT 'patient1', '2024-04-02'
UNION ALL
SELECT 'patient1', '2024-04-15'
UNION ALL
SELECT 'patient2', '2024-04-15'),
available_sessions_per_transfer AS (SELECT sessions.patient, session_date, transfer_date
FROM sessions
JOIN unit_transfers ON sessions.patient = unit_transfers.patient
AND sessions.session_date >= transfer_date),
patients_with_erliest_transfer_date_per_session AS (SELECT latest.patient, latest.session_date, transfer_date
FROM available_sessions_per_transfer available
JOIN (SELECT patient, session_date, max(transfer_date) latest_transfer_date
FROM available_sessions_per_transfer
GROUP BY patient, session_date) latest
ON available.patient = latest.patient AND
available.session_date =
latest.session_date AND
available.transfer_date =
latest.latest_transfer_date)
SELECT *
FROM patients
LEFT JOIN patients_with_erliest_transfer_date_per_session
ON patients.patient = patients_with_erliest_transfer_date_per_session.patient;