SQL MAX()函数返回所有结果

时间:2015-03-15 15:47:50

标签: sql sql-server sql-server-2012 greatest-n-per-group

首先,我想通过让每个人都知道我对sql和编码一般都是新手来解释这个问题。我有一个问题:

    Select Distinct 
[t1].[Name] AS Subdivision
, [t2].[Description] AS SubStatus
, [t4].[Name] AS ConnectingSubName
, [t2].[Description] As ConnectingSubStatus
, [t5].[ActualPublicationEndDate]
, MAX([t5].[version]) as Version

From [PtcDbTracker].[dbo].[TrackDatabase] as [t0]
INNER Join [PTCDbTracker].[dbo].[Subdivision] as [t1] on [t0].   [SubdivisionId]=[t1].[SubdivisionId]
Inner Join [PTCDbTracker].[dbo].[Status] as [t2] on [t1].[StatusId]=[t2].[StatusId]
Inner Join [PTCDbTracker].[dbo].[ConnectingSubs] as [t3] on [t0].[SubdivisionId]=[t3].[SubdivisionId] 
Inner Join [PTCDbTracker].[dbo].[Subdivision] as [t4] on ([t2].[StatusId]=[t4].[StatusId] AND [t3].[ConnectingSubId]=[t4].[SubdivisionId])
Inner Join [PtcDbTracker].[dbo].[TrackDatabase] as [t5] on t3.ConnectingSubId = t5.SubdivisionId

Where [t0].[SubdivisionId] = '90'
AND [t5].[Version] BETWEEN 8000 AND 9000

Group By t1.Name, t2.Description, t4.Name, t2.Description, t5.ActualPublicationEndDate

返回:

Subdivision     SubStatus    ConnectingSubName  ConnectingSubStatus       ActualPublicationEndDate      Version
San Bernardino  In Editing   Alameda Corridor   In Editing                2013-12-17 00:00:00.0000000   8000
San Bernardino  In Editing   Harbor             In Editing                2014-04-25 00:00:00.0000000   8001
San Bernardino  In Editing   Alameda Corridor   In Editing                2014-05-01 00:00:00.0000000   8001
San Bernardino  In Editing   Alameda Corridor   In Editing                2014-09-25 00:00:00.0000000   8002

我真正想要返回的是第2行和第4行。我知道Group By子句正在创建1的组,但如果我尝试取出任何东西,我会收到错误。任何帮助将不胜感激。我正在使用MS Sql SMS 2012。

3 个答案:

答案 0 :(得分:1)

您的查询中的问题是ActualPublicationEndDate中的group by列,您需要将其从group byselect列表中删除

相反,您可以使用Row_Number查找每version的最大Subdivision, SubStatus, ConnectingSubName and ConnectingSubStatus

Select *
from 
(
select *,
       row_number() over(partition by Subdivision, SubStatus, ConnectingSubName, ConnectingSubStatus 
                          order by [t5].[version] desc) RN
From join..
..
) A
where RN=1

答案 1 :(得分:1)

您想使用row_number()。像这样:

with t as (
      Select [t1].[Name] AS Subdivision, [t2].[Description] AS SubStatus,
             [t4].[Name] AS ConnectingSubName, [t2].[Description] As ConnectingSubStatus,
             [t5].[ActualPublicationEndDate], [t5].[version] as Version
      From [PtcDbTracker].[dbo].[TrackDatabase] [t0] INNER Join
           [PTCDbTracker].[dbo].[Subdivision] [t1]
           on [t0].[SubdivisionId] = [t1].[SubdivisionId] Inner Join
           [PTCDbTracker].[dbo].[Status] [t2]
           on [t1].[StatusId]=[t2].[StatusId] Inner Join
           [PTCDbTracker].[dbo].[ConnectingSubs] [t3]
           on [t0].[SubdivisionId]=[t3].[SubdivisionId] Inner Join
           [PTCDbTracker].[dbo].[Subdivision] [t4]
           on ([t2].[StatusId]=[t4].[StatusId] AND [t3].[ConnectingSubId]=[t4].[SubdivisionId]) Inner Join
          [PtcDbTracker].[dbo].[TrackDatabase] [t5]
           on t3.ConnectingSubId = t5.SubdivisionId
      Where [t0].[SubdivisionId] = '90' AND [t5].[Version] BETWEEN 8000 AND 9000
     )
select t.*
from (select t.*,
             row_number() over (partition by Subdivision, SubStatus,   ConnectingSubName
                                order by version desc) as seqnum
      from t
     ) t
where seqnum = 1

这使用row_number()获取每个实体的最大版本的行,然后返回该行。

答案 2 :(得分:0)

看起来你是来自TrackDatabase的最高版本的行。一种方法是row_number()。一个简化的例子:

select  *
from    T1
join    (
        select  row_number() over (
                    partition by ConnectingSubId
                    order by version desc) as rn
        ,       *
        from    T2
        ) as t2
on      t1.SubId = t2.ConnectingSubId
        and t2.rn = 1 -- Latest version only

带有子查询的join的优点是您只需要按一列进行分区。