左加入具有特定条件的子查询

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 aLEFT 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

有几种方法可以做到这一点。不过,我对您的数据做了一些假设。

  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;
    
  2. 使用APPLYTOP
    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;
    
  3. 使用 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;
    
  4. 使用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 将不会按预期工作。