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从多个列中获取最大值的主要内容,如果未能解决你的问题,请参考以下文章