sql - 是否有替代子选择上的多个左连接的替代方法?
问题描述
我有一个历史记录表,每次组成员确认一个项目时都会对其进行跟踪,记录组 ID、项目 ID、历史 ID 和 history_time。我的前任创建的视图部分从中提取,以返回给定项目 ID 的每个组 ID 的 MAX(history_time),以便仅返回组确认项目的最近日期,如果组尚未确认则返回 null它。这导致这部分视图依赖于 24 LEFT JOINS。
一个简化的例子如下:
SELECT * FROM
ITEM_TABLE item LEFT OUTER JOIN
(SELECT ITEM_ID, MAX(HISTORY_TIME) AS [202_TIME]
FROM dbo.HISTORY AS HISTORY_1
WHERE (GROUP_ID = 202)
GROUP BY ITEM_ID) AS h1 ON h1.ITEM_ID = item.ITEM_ID LEFT OUTER JOIN
(SELECT ITEM_ID, MAX(HISTORY_TIME) AS [145_TIME]
FROM dbo.HISTORY AS HISTORY_2
WHERE (GROUP_ID = 145)
GROUP BY ITEM_ID) AS h2 ON h2.ITEM_ID = item.ITEM_ID LEFT OUTER JOIN
....
FROM 子句中的子选择对每个组(20+)重复。在我看来,这似乎很混乱。我尝试用一个大选择替换所有这些额外的连接,该选择利用 ROW_NUMBER() OVER PARTITION 聚合数据并将其推送到 PIVOT 表中。虽然我觉得这看起来好多了,但它显然比我想要的要慢。
有没有比从子选择上的多个连接中选择更清洁、更容易阅读或更有效的替代方法?
解决方案
您可以尝试使用 max(case 表达式) 来使用单个选择找出每个组 id 的 max_timings,如下所示
SELECT *
FROM ITEM_TABLE item
LEFT JOIN (SELECT ITEM_ID
, MAX(CASE WHEN GROUP_ID=202 THEN HISTORY_TIME END) AS [202_TIME]
, MAX(CASE WHEN GROUP_ID=145 THEN HISTORY_TIME END) AS [145_TIME]
FROM dbo.HISTORY
WHERE (GROUP_ID in (202,145,...)
GROUP BY ITEM_ID)h1
ON h1.ITEM_ID = item.ITEM_ID
推荐阅读
- excel - 将工作簿中具有相同列范围的工作表拆分为使用 VBA 代码分隔 Excel 文件
- arrays - 调用函数时出现不兼容的类型错误
- c - 显示本地时间和 UTC 时间
- java - 如何将数组初始化为空?
- elixir - 有没有更简单的方法来获取与函数匹配的列表中的第一个项目,并返回该项目以及没有该项目的列表?
- npm - NPM 错误:EPERM:不允许操作。压缩包数据
似乎被破坏了 - laravel - 如何在 Raspberry Pi 上托管 Laravel 项目
- python - 上传amazon s3 python,boto3后获取文件url
- ibm-cloud - IBM Cloud App ID:忘记密码和重新认证流程
- spring - Spring Boot 和 Spring Cloud 上的服务发现错误