如何从每组中获得前 1 行? (T-SQL)

Posted

技术标签:

【中文标题】如何从每组中获得前 1 行? (T-SQL)【英文标题】:How do I get the top 1 row from each group? (T-SQL) 【发布时间】:2016-10-24 15:37:59 【问题描述】:

我有一张如下所示的表格:

ID    Month    Year
 1      3       2016
 1      5       2016
 1      2       2016
 2      3       2016
 2      1       2015
 2      NULL    NULL
 3      NULL    NULL
etc...

我想为每个 id 选择 1 行,最大年份,然后是月份,如果没有其他选择,则为 NULL,因此结果如下:

ID    Month    Year
1      5       2016
2      3       2016
3      NULL    NULL

这是我当前查询的样子:

SELECT distinct
LogTable.CaseID,
Monthlies.Month,
Monthlies.Year
FROM [LogTable]
LEFT JOIN CTable
on LogTable.SerialNum = CTable.SERIAL_NUM
LEFT JOIN 
tCaseStatus AS CaseStatus ON CaseStatus.CaseGUID = LogTable.CaseGUID LEFT JOIN
tReferredBy AS ReferredBy ON ReferredBy.ReferredByGUID =   LogTable.ReferredByGUID LEFT JOIN
placements AS Placement ON Placement.LogGUID = LogTable.LogGUID LEFT JOIN
PlacementMonth AS Monthlies ON Monthlies.PlacementRowGUID = Placement.PlacementRowGUID LEFT JOIN
tRC AS RC ON RC.RCGUID = LogTable.RCGUID LEFT JOIN
VendorH ON VendorH.LogGUID = LogTable.LogGUID LEFT JOIN
tVendor AS Vendor ON Vendor.VendorGUID = VendorH.VendorGUID 
where CaseStatus.Name = 'Active'
order by Monthlies.Year DESC , Monthlies.Month desc

我尝试在表上进行外部应用,从月份和年份开始选择外部应用内 desc 月份和年份的第一行,但我得到了一些 Id 的多行。

【问题讨论】:

看看ROW_NUMBER:) 您还应该考虑使用一个日期字段而不是月份和年份。这使得很多操作变得更加容易。 为什么不分组?select id, max([month]), max([year]) from LogTable group by id 【参考方案1】:

这种请求可以使用ROW_NUMBER处理

select * from 
(
select row_number() over(partition by ID order by [year] desc,[month] desc) as rn,*
From yourresult
) A
Where RN = 1

【讨论】:

@JohnHC - 不能同意更多......只是懒惰......虽然我永远不会这样做INSERTMERGE声明【参考方案2】:
with CTE as
(
select ID, Month, Year, row_number() over(partition by ID order by Year desc, Month desc) as ROW_ORD
from Table1
)
select ID, Month, Year
from CTE
where ROW_ORD = 1

【讨论】:

【参考方案3】:

首先,如果可能,我会避免列名是 SQL 中的关键字,即月份和年份。使用后可以达到你想要的效果:

ROW_NUMBER:

返回结果集分区内行的序号,每个分区的第一行从 1 开始。

可运行示例:

CREATE TABLE #LogTable
    (
      [ID] INT ,
      [Month] INT ,
      [Year] INT
    );

INSERT  INTO #LogTable
        ( [ID], [Month], [Year] )
VALUES  ( 1, 3, 2016 ),
        ( 1, 5, 2016 ),
        ( 1, 2, 2016 ),
        ( 2, 3, 2016 ),
        ( 2, 1, 2015 ),
        ( 2, NULL, NULL ),
        ( 3, NULL, NULL );

SELECT  t.ID ,
        t.Month ,
        t.Year
FROM    ( SELECT    ID ,
                    [Month] ,
                    [Year] ,
                    ROW_NUMBER() OVER ( PARTITION BY ID ORDER BY [Year] DESC, [Month] DESC ) row
          FROM      #LogTable
        ) t
WHERE   t.row = 1

DROP TABLE  #LogTable

生产:

ID  Month   Year
1   5       2016
2   3       2016
3   NULL    NULL

【讨论】:

以上是关于如何从每组中获得前 1 行? (T-SQL)的主要内容,如果未能解决你的问题,请参考以下文章

从每组 sqlite 中选择前 n 条记录

如何在大数据帧的每组中有效地随机标记行?

如何在 Oracle 的组中获得第三个 [重复]

有没有办法从每组行中获取 2 行? [复制]

如何获得组中“中间”值的平均值?

如何从 T-SQL 中的表中选择前 N 行?