如何从一组小于另一个表的最大日期的日期中选择一个最大日期?

问题描述 投票:0回答:2

问题:

如何从

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

输出片段:

Output Sample

注意

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'
    ,因为这是该患者的最大转移日期,小于该患者的最大疗程日期。如果我能更好地清理它,请告诉我。

sql subquery max aggregate ingres
2个回答
2
投票

添加

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
                            )

0
投票

这是一个非常老的问题,但我有一个非常相似的问题,不得不敲了几个小时才能解决它,如果我正确理解需要做什么,这应该能够为发现这个问题的任何人提供帮助谷歌提问。

假设我们有下一个数据

患者

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;
© www.soinside.com 2019 - 2024. All rights reserved.