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

Posted

技术标签:

【中文标题】MSSQL通过ID从多个列中获取最大值【英文标题】:MSSQL Get max value from multiple columns by an ID 【发布时间】:2014-06-05 18:26:03 【问题描述】:

我在这方面遇到过很多类似的帖子,但我没有找到具体的。

这是我的示例数据:

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 和 NARID 的最大 NADate:

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。

【问题讨论】:

+1 表示在一个相对常见的问题上实际上有一个不太常见的变体。 【参考方案1】:

我认为最简单的方法是使用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(),以便返回最近日期的所有行。

【讨论】:

您在cid 上进行分组,但问题要求在cid, narid 上进行分组。另外,如果你投as date,你将丢弃订购的时间部分 根据您的解决方案进行了一些修改,这就是诀窍: SELECT t.* FROM ( SELECT t.*, dense_rank() OVER ( PARTITION BY cid, narid ORDER BY nadate DESC, aedate DESC ) AS seqnum FROM TABLE t ) t WHERE seqnum = 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

【讨论】:

如果您的数据中可能有两条相同的记录(ID 除外),则此解决方案似乎将排除上述使用 dense_rank() 的解决方案没有的重复行。虽然这种情况永远不会出现在我的数据中,但它也是一个可行的解决方案,可能适用于出现重复行的其他情况。在 row_number() 之前添加 *, 是显示所有列所必需的。【参考方案3】:
    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;

【讨论】:

这将抓住顶部nadate,但它不会使用aedate解决平局

以上是关于MSSQL通过ID从多个列中获取最大值的主要内容,如果未能解决你的问题,请参考以下文章

在Laravel中获取具有不同外国ID的列中的最大值

从具有联合的两个表中选择一列中最大值的所有行

获取数组列中的最小值和最大值

如何检索表的值以获取sql中两列的最大值

如何从 SQL Server 中的同一列中查找多个最大值

mssql 的 存储过程 变量赋值问题