【问题标题】:How to select distinct rows but max of date?如何选择不同的行但最大日期?
【发布时间】:2019-10-17 11:26:01
【问题描述】:

假设我有一张桌子:

Table A
Period Name| Type Name|    Date     | Quantity
-----------------------------
Yearly  | General | 2019-09-01  | 24
Yearly  | General | 2019-11-01  | 30
Yearly  | Casual  | 2019-09-01  | 6

我想按 PeriodName、TypeName 但 Max of date 获取所有行分组。

我按最大日期分组,然后加入原始表以获得结果:

SELECT     dbo.tbl_WPT_LeaveType.TypeName, dbo.tbl_WPT_EmployeeLeavePolicy.FK_tbl_WPT_LeaveType_ID, dbo.tbl_WPT_LeavePeriod.PeriodName, 
                      dbo.tbl_WPT_EmployeeLeavePolicy.FK_tbl_WPT_LeavePeriod_ID, dbo.tbl_WPT_EmployeeLeavePolicy.Leave, dbo.tbl_WPT_EmployeeLeavePolicy.WithOutRequest, 
                      dbo.tbl_WPT_EmployeeLeavePolicy.ApplyFrom
FROM         dbo.tbl_WPT_EmployeeLeavePolicy INNER JOIN
                      dbo.tbl_WPT_LeaveType ON dbo.tbl_WPT_EmployeeLeavePolicy.FK_tbl_WPT_LeaveType_ID = dbo.tbl_WPT_LeaveType.ID INNER JOIN
                      dbo.tbl_WPT_LeavePeriod ON dbo.tbl_WPT_EmployeeLeavePolicy.FK_tbl_WPT_LeavePeriod_ID = dbo.tbl_WPT_LeavePeriod.ID INNER JOIN
   ---------same table to get max date                   
                          (SELECT     TOP (100) PERCENT MAX(tbl_WPT_EmployeeLeavePolicy_1.ApplyFrom) AS ApplyFrom, tbl_WPT_EmployeeLeavePolicy_1.FK_tbl_WPT_LeaveType_ID, 
                                                   tbl_WPT_EmployeeLeavePolicy_1.FK_tbl_WPT_LeavePeriod_ID
                            FROM          dbo.tbl_WPT_EmployeeLeavePolicy AS tbl_WPT_EmployeeLeavePolicy_1 INNER JOIN
                                                   dbo.tbl_WPT_LeaveType AS tbl_WPT_LeaveType_1 ON tbl_WPT_EmployeeLeavePolicy_1.FK_tbl_WPT_LeaveType_ID = tbl_WPT_LeaveType_1.ID INNER JOIN
                                                   dbo.tbl_WPT_LeavePeriod AS tbl_WPT_LeavePeriod_1 ON tbl_WPT_EmployeeLeavePolicy_1.FK_tbl_WPT_LeavePeriod_ID = tbl_WPT_LeavePeriod_1.ID
                            WHERE      (tbl_WPT_EmployeeLeavePolicy_1.FK_tbl_WPT_Employee_ID = @EmpID) AND (tbl_WPT_EmployeeLeavePolicy_1.FK_tbl_WPT_LeavePeriod_ID = 2) AND 
                                                   (tbl_WPT_EmployeeLeavePolicy_1.ApplyFrom <= @MonthFrom)
                            GROUP BY tbl_WPT_EmployeeLeavePolicy_1.FK_tbl_WPT_LeaveType_ID, tbl_WPT_EmployeeLeavePolicy_1.FK_tbl_WPT_LeavePeriod_ID) AS x ON x.FK_tbl_WPT_LeaveType_ID = dbo.tbl_WPT_EmployeeLeavePolicy.FK_tbl_WPT_LeaveType_ID AND x.FK_tbl_WPT_LeavePeriod_ID = dbo.tbl_WPT_EmployeeLeavePolicy.FK_tbl_WPT_LeavePeriod_ID AND x.ApplyFrom = dbo.tbl_WPT_EmployeeLeavePolicy.ApplyFrom


WHERE     (dbo.tbl_WPT_EmployeeLeavePolicy.FK_tbl_WPT_Employee_ID = @EmpID) AND (dbo.tbl_WPT_EmployeeLeavePolicy.FK_tbl_WPT_LeavePeriod_ID = 2) AND 
                      (dbo.tbl_WPT_EmployeeLeavePolicy.ApplyFrom <= @MonthFrom)


Period Name| Type Name|    Date     | Quantity
-----------------------------------------------
Yearly  | General | 2019-11-01  | 30
Yearly  | Casual  | 2019-09-01  | 6

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008


    【解决方案1】:

    我建议使用公用表表达式和row_number() 函数来识别具有最大日期的记录。

    例如:

    create table #test (
        [Period Name] varchar(20),
        [Type Name] varchar(20),
        [Date] date,
        Quantity int
    )
    insert #test values ('Yearly', 'General', '2019-09-01', 24)
                      , ('Yearly', 'General', '2019-11-01', 30)
                      , ('Yearly', 'Casual', '2019-09-01', 6)
    
    ;with c as (select [Period Name]
                     , [Type Name]
                     , [Date]
                     , Quantity
                     , row_number() over (partition by [Period Name], [Type Name] order by [date] desc) rn
                  from #test
                  )
    select *
      from c
     where rn = 1
    

    结果:

    Period Name Type Name   Date    Quantity    rn
    Yearly  Casual  2019-09-01  6   1   
    Yearly  General 2019-11-01  30  1   
    

    【讨论】:

    • 谢谢,完美答案
    猜你喜欢
    • 1970-01-01
    • 2014-07-26
    • 2014-01-24
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多