左加入具有特定条件的子查询
LEFT Join on a Subquery with specific criteria
我有两个表要加入
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
Select - 但是,我只想 select 表 2 中的 ID MAX(EndDt)
Select a.*, b.SomeVal
from table1 a
LEFT OUTER JOIN table2 b on a.id=b.id // and b.MAX(EndDt)
这样的事情可行吗?
我建议使用窗口 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
对于单个值,使用相关子查询:
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
有几种方法可以做到这一点。不过,我对您的数据做了一些假设。
- 对子查询使用
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
在 table Table1
中不是唯一的(因此我对您的数据做出了假设),选项 3 和 4 将不会按预期工作。
我有两个表要加入
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
Select - 但是,我只想 select 表 2 中的 ID MAX(EndDt)
Select a.*, b.SomeVal
from table1 a
LEFT OUTER JOIN table2 b on a.id=b.id // and b.MAX(EndDt)
这样的事情可行吗?
我建议使用窗口 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
对于单个值,使用相关子查询:
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
有几种方法可以做到这一点。不过,我对您的数据做了一些假设。
- 对子查询使用
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
在 table Table1
中不是唯一的(因此我对您的数据做出了假设),选项 3 和 4 将不会按预期工作。