5

抱歉标题模棱两可,不知道如何搜索,或者问这个问题。

假设我们有 TableA:

RowID FkId 排名日期
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 & Rank 获取 MAX(Date) 组。

选择表 A.*
(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
在 s2.FkId = TableA.FkId AND s2.Rank = TableA.Rank AND s2.Date = TableA.Date 上的内部连接 ​​TableA

是否有更有效的查询可以达到相同的结果?感谢您的关注。

编辑:自上次回答以来添加了 ID5。如果我尝试正常的 MAX(rank),MAX(Date) GROUP BY FkId,那么对于“A”,我会得到 A;2;2013 年 3 月 5 日。此结果与 RowId 不匹配。

4

4 回答 4

4

您可以使用ROW_NUMBERCTE 假设 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
于 2013-03-25T21:10:02.813 回答
2

您的问题(在对此答案的评论中澄清)要求:

  1. 每个 FkId 一行
  2. 最大日期和排名
  3. 结果对应于原始数据中的一行。

如果 FkId 的行中最大日期和最大排名位于不同的行中,则您必须至少放宽其中一项要求。

如果您愿意放宽要求(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

这是一个sqlfiddle 来展示它

于 2013-03-25T21:05:45.467 回答
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 ) 

SQL 小提琴演示

于 2013-03-25T21:48:37.900 回答
0

你也可以偷偷摸摸地完成 ljh 这样的建议

select top 1 with ties *
from TableA
order by rank() over (
  partition by FKID
  order by [Rank] desc, [Date] desc
)
于 2013-03-25T23:10:04.277 回答