在具有特定条件的子查询上左连接
Posted
技术标签:
【中文标题】在具有特定条件的子查询上左连接【英文标题】:LEFT Join on a Subquery with specific criteria 【发布时间】:2021-11-11 15:07:24 【问题描述】:我有两个要加入的表
table1
----------------------------
Id Name Num
123X Apple 17
table2
-------------------------------------------------
id EndDt SomeVal
123X 10/1/2021 xxx
123X 3/1/2022 yyy
我正在尝试从 table1 a
和 LEFT JOIN table2 b on a.id = b.id
中进行选择 - 但是,我只想在 table2 中的 ID 上选择 MAX(EndDt)
Select a.*, b.SomeVal
from table1 a
LEFT OUTER JOIN table2 b on a.id=b.id // and b.MAX(EndDt)
这样的事情可行吗?
【问题讨论】:
再添加几行样本数据,同时指定预期结果。 【参考方案1】:有几种方法可以做到这一点。不过,我对您的数据做了一些假设。
-
将
LEFT JOIN
与子查询一起使用:
SELECT T1.*,
sq.SomeVal
FROM dbo.Table1 T1
LEFT JOIN (SELECT ROW_NUMBER() OVER (PARTITION BY t2.Id ORDER BY t2.EndDt DESC) AS RN,
t2.Id,
t2.SomeVal
FROM dbo.Table2 T2) sq ON T1.Id = T2.Id
AND T2.RN = 1;
使用APPLY
和TOP
:
SELECT T1.*,
sq.SomeVal
FROM dbo.Table1 T1
OUTER APPLY (SELECT TOP (1)
t2.Id,
t2.SomeVal
FROM dbo.Table2 T2
WHERE T2.Id = T1.Id
ORDER BY T2.EndDt DESC) sq;
使用 CTE 并获取每组的“前 1”行:
WITH CTE AS(
SELECT T1.*,
T2.SomeVal,
ROW_NUMBER() OVER (PARTITION BY T1.ID ORDER BY T2.MaxDt DESC) AS RN
FROM dbo.Table1 T1
LEFT JOIN dbo.Table2 T2 ON T1.Id = T2.Id)
SELECT *
FROM CT
WHERE RN = 1;
使用TOP (1) WITH TIES
:
SELECT TOP (1) WITH TIES
T1.*,
T2.SomeVal
FROM dbo.Table1 T1
LEFT JOIN dbo.Table2 T2 ON T1.Id = T2.Id
ORDER BY ROW_NUMBER() OVER (PARTITION BY T1.ID ORDER BY T2.MaxDt DESC) ASC;
请注意,如果 ID
在表 Table1
中不是唯一的(因此我对您的数据做出假设),选项 3 和 4 将无法按预期工作。
【讨论】:
【参考方案2】:我建议先使用窗口化的 ROW_NUMBER 函数获取最大值 table2
,然后加入该子查询。
;WITH cte AS (
SELECT *, [Row] = ROW_NUMBER() OVER (PARTITION BY b.Id ORDER BY b.EndDt DESC)
FROM table2 b
)
SELECT a.*, cte.SomeVal
FROM table1 a
LEFT JOIN cte ON a.id = cte.id AND cte.[Row] = 1
【讨论】:
【参考方案3】:对于单个值,使用相关子查询:
SELECT
a.id,
a.name,
a.num,
(
SELECT TOP 1 SomeValue
FROM table2 As b
WHERE b.id = a.id
ORDER BY b.EndDt DESC
) As SomeVal
FROM
table1 a
【讨论】:
以上是关于在具有特定条件的子查询上左连接的主要内容,如果未能解决你的问题,请参考以下文章