MSSQL通过ID从多列获取最大值

时间:2014-06-05 18:26:03

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

我在这方面遇到过很多类似的帖子,但我发现这些帖子都没有具体说明。

这是我的示例数据:

ID      CID     NARID   NATID       NADate      EID     AEDate
1       1655    1       4           12/1/12     202     6/4/14 11:37:01
2       1655    1       7           12/1/12     202     6/4/14 11:37:12
5       1655    2       65          1/13/14     587     6/4/14 11:37:00
29      3165    1       6           4/15/14     7       6/4/14 11:37:00
300     3165    1       6           6/30/14     7       6/4/14 11:33:50
295     3165    2       64          6/11/14     7       6/4/14 11:37:00
302     3165    2       63          7/24/14     7       6/4/14 11:41:24
303     3165    2       67          7/24/14     7       6/4/14 15:59:06

我首先想要获得每个CID&的最大NADate。 NARID:

ID      CID     NARID   NATID       NADate      EID     AEDate
1       1655    1       4           12/1/12     202     6/4/14 11:37:01
2       1655    1       7           12/1/12     202     6/4/14 11:37:12
5       1655    2       65          1/13/14     587     6/4/14 11:37:00
300     3165    1       6           6/30/14     7       6/4/14 11:33:50
302     3165    2       63          7/24/14     7       6/4/14 11:41:24
303     3165    2       67          7/24/14     7       6/4/14 15:59:06

然后从这些结果中获取最大AEDate(以及所有其他相应字段)的记录:

ID      CID     NARID   NATID       NADate      EID     AEDate
2       1655    1       7           12/1/12     202     6/4/14 11:37:12
5       1655    2       65          1/13/14     587     6/4/14 11:37:00
300     3165    1       6           6/30/14     7       6/4/14 11:33:50
303     3165    2       67          7/24/14     7       6/4/14 15:59:06

数据库类型是MSSQL 2005。

3 个答案:

答案 0 :(得分:3)

我认为最简单的方法是使用dense_rank()

select t.*
from (select t.*,
             dense_rank() over (partition by cid
                                order by nadate desc, cast(edate as date) desc
                               ) as seqnum
      from table t
     ) t
where seqnum = 1;

您需要cast(edate to date),因此查询将仅考虑edate的日期部分。您需要dense_rank(),以便返回最近日期的所有行。

答案 1 :(得分:2)

您可以使用row_number()在每个(cid, narid)组中分配号码。如果您分配按nadate desc, aedate desc排序的行号,则行号1的行将是您要查找的行:

select  *
from    (
        select  row_number() over (
                    partiton by cid, narid
                    order by nadate desc, aedate desc) as rn
        ,       *
        from    YourTable
        ) as SubQueryAlias
where   rn = 1

答案 2 :(得分:0)

    WITH TEMP AS
        (    
        SELECT CID,NARID,MAX(NADATE)  AS TEMPDATE
        FROM TABLE
        GROUP BY CID,NARID
        )
    SELECT A.ID,A.CID,A.NARID,A.NATID,A.NADate,A.EID,MAX(A.AEDate)
      FROM TABLE A INNER JOIN TEMP 
    ON A.CID=TEMP.CID AND A.NARID=TEMP.NARID AND A.NADATE=TEMP.TEMPDATE
    GROUP BY A.ID,A.CID,A.NARID,A.NATID,A.NADate,A.EID;