使用 4 个表的 SQL MAX 查询

Posted

技术标签:

【中文标题】使用 4 个表的 SQL MAX 查询【英文标题】:SQL MAX query using 4 tables 【发布时间】:2018-10-30 01:13:25 【问题描述】:

我在从 SQL 数据库中获取信息时遇到了困难。

我正在使用的表格如下所示:

表:system.episode_history +------------+----------------+------------+------ ----------+ |患者 ID |剧集编号 |承认日期 |出院日期 | +------------+----------------+------------+------ ----------+ | 111 | 4 | 2017 年 1 月 5 日 | | +------------+----------------+------------+------ ----------+ | 222 | 8 | 2017 年 3 月 17 日 | | +------------+----------------+------------+------ ----------+ | 222 | 9 | 2017 年 3 月 20 日 | | +------------+----------------+------------+------ ----------+ | 333 | 2 | 2017 年 10 月 8 日 | | +------------+----------------+------------+------ ----------+ |第444章7 | 2017 年 8 月 9 日 | 2017 年 8 月 20 日 | +------------+----------------+------------+------ ----------+ 表:system.view_episode_summary_current +------------+----------------+------------+------ ----------------+ |患者 ID |剧集编号 |承认日期 | last_date_of_service | +------------+----------------+------------+------ ----------------+ | 111 | 4 | 2017 年 1 月 5 日 | 2017 年 11 月 1 日 | +------------+----------------+------------+------ ----------------+ | 222 | 8 | 2017 年 3 月 17 日 | 2017 年 11 月 3 日 | +------------+----------------+------------+------ ----------------+ | 222 | 9 | 2017 年 3 月 20 日 | 2017 年 11 月 4 日 | +------------+----------------+------------+------ ----------------+ | 333 | 2 | 2017 年 10 月 8 日 | 2017 年 11 月 5 日 | +------------+----------------+------------+------ ----------------+ 表:system.history_attending_practitioner +------------+----------------+----------------- --+------------------------+ |患者 ID |剧集编号 |参加者 |实践分配日期 | +------------+----------------+----------------- --+------------------------+ | 111 | 4 | 4444 | 2017 年 1 月 5 日 | +------------+----------------+----------------- --+------------------------+ | 222 | 8 | 5555 | 2017 年 3 月 17 日 | +------------+----------------+----------------- --+------------------------+ | 222 | 8 | 6666 | 2017 年 3 月 20 日 | +------------+----------------+----------------- --+------------------------+ | 222 | 9 | 7777 | 2017 年 4 月 10 日 | +------------+----------------+----------------- --+------------------------+ | 333 | 2 | 5555 | 2017 年 10 月 8 日 | +------------+----------------+----------------- --+------------------------+ |第444章7 | 7777 | 2017 年 8 月 9 日 | +------------+----------------+----------------- --+------------------------+ 表:system.user_practitioner_assignment +------------+----------------+----------------- --+--------------------+ |患者 ID |剧集编号 |备份从业者 | date_of_assignment | +------------+----------------+----------------- --+--------------------+ | 111 | 4 | | | +------------+----------------+----------------- --+--------------------+ | 222 | 8 | 7777 | 2017 年 3 月 17 日 | +------------+----------------+----------------- --+--------------------+ | 222 | 8 | 4444 | 2017 年 5 月 18 日 | +------------+----------------+----------------- --+--------------------+ | 222 | 9 | | | +------------+----------------+----------------- --+--------------------+ | 333 | 2 | 4444 | 2017 年 10 月 8 日 | +------------+----------------+----------------- --+--------------------+ | 333 | 2 | 5555 | 2017 年 10 月 19 日 | +------------+----------------+----------------- --+--------------------+

我需要 SQL 查询来返回这样的表:

+-------------+------------+----------------+----- -------+--------------------+---------- -+ | ?Staff_ID |患者 ID |剧集编号 |承认日期 | date_of_assignment | last_date_of_service | +-------------+------------+----------------+----- -------+--------------------+---------- -+ | 4444 | 111 | 4 | 2017 年 1 月 5 日 | 2017 年 1 月 5 日 | 2017 年 11 月 1 日 | +-------------+------------+----------------+----- -------+--------------------+---------- -+ | 4444 | 222 | 8 | 2017 年 3 月 17 日 | 2017 年 5 月 18 日 | 2017 年 11 月 3 日 | +-------------+------------+----------------+----- -------+--------------------+---------- -+

我正在使用 system.episode_history 表来确定是否有与剧集相关的出院日期。

在哪里(system.episode_history.discharge_date 为空)

我正在使用 system.view_episode_summary_current 表来获取连接到剧集的最后服务日期。

我尝试了几件事,但都没有成功。

首先,SQL 处理程序似乎对查询中的别名变化无常。我还没想好如何安抚它。

其次,SQL 句柄似乎已经足够老了,以至于它不知道如何处理 SQL 窗口函数,例如 OVER、LAG()、LEAD() 等。所以我只剩下弄清楚如何将自连接与 MAX() 函数一起使用。我认为这是一个较旧的 SAP SQL 服务器。

我是 SQL 的新手。例如,根据我的观察,我假设 SQL 查询中的大写(大部分)无关紧要,但我不确定。我一直在互联网上寻求帮助,但没有找到任何可以让我工作或理解的有用信息(此时大部分感觉就像一门外语)。那些我在工作内外都知道 SQL 的人很难过,但这一点。我在这里已经超出了我的深度,所以任何帮助都将不胜感激。

更新 1

我调整了下面的建议查询,直到没有错误为止,并最终得到如下所示的查询:

select staff.staff_id, epi.patient_id, epi.episode_number as episode_id, epi.admit_date, staff.date_of_assignment, curr.last_date_of_service
from system.episode_history as epi
join (
    select patient_id, episode_number, attend_practitioner as staff_id, pract_assignment_date as date_of_assignment 
    from system.history_attending_practitioner
    union
    select patient_id, episode_number, backup_practitioner as staff_id, date_of_assignment as date_of_assignment 
    from system.user_practitioner_assignment
    where (backup_practitioner is not null)
    ) as staff on staff.patient_id=epi.patient_id and staff.episode_number=epi.episode_number
    and not exists(select * from system.history_attending_practitioner as a2 where a2.patient_id=staff.patient_id and a2.episode_number=staff.episode_number and a2.pract_assignment_date>staff.date_of_assignment)
    and not exists(select * from system.user_practitioner_assignment as a3 where a3.patient_id=staff.patient_id and a3.episode_number=staff.episode_number and a3.date_of_assignment>staff.date_of_assignment)
join system.view_episode_summary_current curr on curr.patient_id=epi.patient_id and curr.episode_number=e.episode_number
where (epi.discharge_date is null)
and staff.staff_id = '4444'

当我对真实数据库运行此查询时,它正确地从 system.history_attending_practitioner 返回了 4 个匹配条目,但只返回了来自 system.user_practitioner_assignment 的 8 个匹配条目中的 1 个。充其量,我之前的无数次尝试只从一个表或另一个表返回结果,但从不返回两者。所以这至少是一个改进。

更新 2

调整查询项的顺序后,这是返回正确结果的版本:

select staff.staff_id, epi.patient_id, epi.episode_number as episode_id, epi.admit_date, staff.date_of_assignment, curr.last_date_of_service
from system.episode_history as epi
join (
    select patient_id, episode_number, attend_practitioner as staff_id, pract_assignment_date as date_of_assignment 
    from system.history_attending_practitioner
    where (attend_practitioner is not null)
    and not exists(select * from system.history_attending_practitioner as a2 where a2.patient_id=system.history_attending_practitioner.patient_id and a2.episode_number=system.history_attending_practitioner.episode_number and a2.pract_assignment_date>system.history_attending_practitioner.pract_assignment_date)
    union
    select patient_id, episode_number, backup_practitioner as staff_id, date_of_assignment as date_of_assignment 
    from system.user_practitioner_assignment
    where (backup_practitioner is not null)
    and not exists(select * from system.user_practitioner_assignment as a3 where a3.patient_id=system.user_practitioner_assignment.patient_id and a3.episode_number=system.user_practitioner_assignment.episode_number and a3.date_of_assignment>system.user_practitioner_assignment.date_of_assignment)
    ) as staff on staff.patient_id=epi.patient_id and staff.episode_number=epi.episode_number
join system.view_episode_summary_current curr on curr.patient_id=epi.patient_id and curr.episode_number=e.episode_number
where (epi.discharge_date is null)
and staff.staff_id = '4444'

【问题讨论】:

这看起来像是多个表之间的简单连接,以及单个 max(last_date_of_service)。你能发布你的sql尝试吗? 在我的回答下方查看新评论。需要发布一个独立示例来展示此解决方案与您想要的结果之间的差距。 【参考方案1】:

这有点难以从您的问题中解决。我认为您需要为每个患者/事件分配最近的任务。

您可以使用 max 使用第二个子查询来执行此操作,或者您可以使用 not exists 如下所示。

正如您所提到的,使用 row_number() 和/或 CTE 会更容易,但这是批量标准 sql 版本。

select s.staff_id, e.patient_id, e.episode_number as episode_id, e.admit_date, s.date_of_assignment, c.last_date_of_service
from episode_history e
join (
    select patient_id, episode_number, attend_practitioner as staff_id, pract_assignment_date as date_of_assignment 
    from history_attending_practitioner
    union
    select patient_id, episode_number, backup_practitioner as staff_id, date_of_assignment as date_of_assignment 
    from user_practitioner_assignment
    where backup_practitioner is not null
    ) s on s.patient_id=e.patient_id and s.episode_number=e.episode_number
    and not exists(select * from history_attending_practitioner a2 where a2.patient_id=s.patient_id and a2.episode_number=s.episode_number and a2.pract_assignment_date>s.date_of_assignment)
    and not exists(select * from user_practitioner_assignment a3 where a3.patient_id=s.patient_id and a3.episode_number=s.episode_number and a3.date_of_assignment>s.date_of_assignment)
join view_episode_summary_current c on c.patient_id=e.patient_id and c.episode_number=e.episode_number
where e.discharge_date is null

【讨论】:

如果 最近分配 backup_practitioner = '4444' 那么我需要请求的其余数据。如果它不是或为空,那么我不需要数据。同样,如果 最近分配attend_practitioner = '4444' 那么我需要请求的其余数据。如果它不是或为空,那么我不需要数据。如果 (system.episode_history.discharge_date IS NULL),那么无论如何我都不需要数据。 我认为这个查询完成了所有@jbh006,我可以看到你现在已经将它包含在你的问题中。我的建议是编辑我们的问题,包括一组数据,这些数据展示了哪些有效和无效,以及您获得的结果和您期望的结果。如果您将数据发布为 create table 语句和 insert 语句,那么人们很容易对数据进行虚拟化并对其进行测试。必须是数据中的某些内容在所有情况下都停止工作。 请参阅更新 2 了解有效的解决方案。谢谢你带我去那里。

以上是关于使用 4 个表的 SQL MAX 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL max 涉及 3 个表的计数

如何使用 3 个表在 SQL 查询中获得完整结果,其中 1 个表保持 2 个表的关系?

SQL - 依赖于 2 个表的查询?

用于连接 5 个表的 SQL 查询 [重复]

如何优化 3 个表的 m:n 关系查询

带有 2 个表的 SQL Server GROUP BY