LEFT OUTER JOIN(选择自表)是否可行?

5

I have two tables Person and Salary.

Person:

PersonId   |  Name   |   Surname
--------------------------------
       1      John          Deer
       2      Mark          Bear

薪资:

SId | PersonId | Date                       | Salary
----------------------------------------------------
1            2   2013-01-01 00:00:00.000      100
2            2   2012-01-01 00:00:00.000      90
3            2   2011-01-01 00:00:00.000      80

我要做的是,如果一个人有薪资记录,那么在结果中应该显示最新的薪资信息。如果没有薪资记录,则应将薪资信息显示为 null。就像这样...

Result
------------------------------------------------------------------------
PersonId   |   Name   | Surname  |  Date                      |  Salary
       1       John        Deer     NULL                            NULL
       2       Mark        Bear     2013-01-01 00:00:00.000         100

我知道应该是这样的,但是由于缺乏知识,我无法实现...

SELECT 
    P.PersonId, P.Name, P.Surname, SL.Date, SL.Salary
FROM 
    PERSON P
LEFT OUTER JOIN 
    (SELECT TOP 1 S.PersonId, S.Date, S.Salary 
     FROM Salary 
     WHERE S.PersonId = P.PersonId ORDER BY Date DESC) SL

6
你已经接近成功了 - 现在你已经设置好了JOIN,唯一缺少的是一个...) SL ON P.PersonId = SL.PersonId连接条件,将这两组数据链接在一起。 - marc_s
1个回答

4

我建议使用CTE和ROW_NUMBER()函数按人员和日期对薪水进行排名。这将把每个人最近的薪水放在第一位,我们可以稍后过滤它(其中rank = 1)。之后,只需从Person连接到别名为CTE的表即可使用简单的LEFT JOIN操作:

WITH RankedSalaries AS
(
    SELECT 
        PersonId
        ,Date
        ,Salary
        ,ROW_NUMBER() OVER (PARTITION BY PersonId ORDER BY Date DESC) AS RowNum
    FROM 
        Salary
)
SELECT 
    p.PersonId
    ,p.Name
    ,p.Surname
    ,s.Date
    ,s.Salary
FROM
    Person p
LEFT JOIN
    RankedSalaries s
    ON
    p.PersonId = s.PersonId
WHERE
    s.RowNum = 1

或者,您可以将CTE的内容移动到您开始的查询的括号之间(即LEFT JOIN (<CTE query>))。只需记住添加= 1限制条件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接