首页 > 解决方案 > 是否有替代子选择上的多个左连接的替代方法?

问题描述

我有一个历史记录表,每次组成员确认一个项目时都会对其进行跟踪,记录组 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 表中。虽然我觉得这看起来好多了,但它显然比我想要的要慢。

有没有比从子选择上的多个连接中选择更清洁、更容易阅读或更有效的替代方法?

标签: sql

解决方案


您可以尝试使用 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

推荐阅读