对于模棱两可的标题,不确定如何搜索或提出此问题,我们深表歉意。
假设我们有TableA:
RowID FkId Rank Date ID1 A 1 2013-3-1 ID2 A 2 2013-3-2 ID3 A 2 2013-3-3 ID4 B 3 2013-3-4 ID5 A 1 2013-3-5
我需要创建一个视图,为每个FkId返回1行。该行应该是最大排名和最大日期。因此对于FkId“A”,查询将返回“ID3”的行。
我能够通过使用子查询返回单行;首先我获得MAX(Rank),然后加入另一个通过FkId&获得MAX(Date)组的查询。秩。
SELECT TableA.* (Select FkId, MAX(Rank) AS Rank FROM TableA GROUP BY FkId) s1 INNER JOIN (Select FkId, Rank, MAX(Date) AS Date FROM TableA GROUP BY FkId,Rank) s2 ON s1.FkId = s2.FkId AND s1.Rank = s2.Rank INNER JOIN TableA ON s2.FkId = TableA.FkId AND s2.Rank = TableA.Rank AND s2.Date = TableA.Date
是否有更高效的查询可以获得相同的结果?谢谢你的期待。
编辑:自上次回答后添加了ID5。如果我尝试了正常的MAX(等级),MAX(日期)GROUP BY FkId,那么对于“A”,我会得到A; 2; 2013年3月5日。此结果与RowId不匹配。
答案 0 :(得分:4)
您可以将ROW_NUMBER
与CTE一起使用(假设sql-server> = 2005):
WITH CTE AS
(
SELECT TableA.*,
RN = ROW_NUMBER() OVER (PARTITION BY FkId Order By Rank Desc, Date DESC)
FROM Table A
)
SELECT RowID,FkId, Rank,Date
FROM CTE WHERE RN = 1
答案 1 :(得分:2)
您的问题(在对此答案的评论中澄清)要求:
如果存在具有行的FkIds,使得最大日期和最大等级位于不同的行中,则必须至少放松其中一个要求。
如果您愿意放宽要求(3),那么您可以使用GROUP BY
:
SELECT FkId, MAX(Rank) AS Rank, Max(Date) AS Date
FROM TableA
GROUP BY FkId
鉴于评论中的额外信息。如果您想要每个FkId中排名最高的最新条目,则以下内容应该有效:
SELECT FkId, Rank, MAX(Date) AS Date
FROM TableA A
WHERE Rank = (SELECT MAX(Rank)
FROM TableA sub
WHERE A.FkId = sub.FkId
GROUP BY sub.FkId)
GROUP BY FkId, Rank
答案 2 :(得分:1)
您可以使用Rank()和内联查询来实现它。
select * from TableA
where RowID in (
select rowID from (
select FKID, RowID,
rank() over (partition by FKID order by [Rank] desc, [Date] desc) as RankNumber
from TableA ) A
where A.RankNumber=1 )
答案 3 :(得分:0)
你也可以偷偷摸摸地完成ljh建议的like this:
select top 1 with ties *
from TableA
order by rank() over (
partition by FKID
order by [Rank] desc, [Date] desc
)