是否可以仅在另一列也相同时使用ROW_NUMBER()OVER/PARTITION BY?

tsd*_*ter 13 sql-server sql-server-2005 row-number common-table-expression

我正在使用此代码:(来自这个问题:如何获取SQL中每个组的最后一条记录替换我自己的列)

WITH e AS
(
 SELECT *,
     ROW_NUMBER() OVER
     (
         PARTITION BY ApplicationId
         ORDER BY theDate DESC
     ) AS Recency
 FROM [Event]
)
SELECT *
FROM e
WHERE Recency = 1
Run Code Online (Sandbox Code Playgroud)

只有当两个字段相同时才可以"分区"吗?例如,我有这样的数据:

ID      Name    theDate
123     John    01/01/2012
123     John    01/02/2012
123     Doe     01/01/2012
456     Smith   02/04/2012
789     Smith   02/01/2012
789     Smith   02/09/2012
789     Roger   02/08/2012
Run Code Online (Sandbox Code Playgroud)

从那些我想要返回的数据:

ID      Name    theDate
123     John    01/02/2012
123     Doe     01/01/2012
456     Smith   02/04/2012
789     Smith   02/09/2012
789     Roger   02/08/2012
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

托马斯

Jef*_*ffO 32

您可以使用逗号分隔多个列

WITH e AS 
( 
 SELECT *, 
     ROW_NUMBER() OVER 
     ( 
         PARTITION BY ApplicationId , Name
         ORDER BY theDate DESC 
     ) AS Recency 
 FROM [Event] 
) 
SELECT * 
FROM e 
WHERE Recency = 1 
Run Code Online (Sandbox Code Playgroud)

  • +1.这完全符合预期,并提供您在问题中要求的确切答案.如果没有,你需要解释如何.我怀疑你实际上没有对它进行过测试,因为你对它如何工作的描述与它的实际效果并不匹配. (2认同)
  • 我同意@AaronBertrand 的评论。我曾多次将 PARTITION BY 与多个列一起使用。JeffO 的例子正是我所使用的。 (2认同)

tsd*_*ter 5

我在这里找到了答案:使用 2 列的表分区

您只能在 1 列上进行分区,但是可以生成该列以创建“多分区”,如下所示:

WITH e AS 
( 
 SELECT *, 
 ROW_NUMBER() OVER 
 ( 
     PARTITION BY CONVERT(VARCHAR(100),ApplicationId) + ' ' + Name
     ORDER BY theDate DESC 
 ) AS Recency 
 FROM [Event] 
) 
SELECT * 
FROM e 
WHERE Recency = 1 
Run Code Online (Sandbox Code Playgroud)

将两列加在一起作为一个字符串可确保仅在两列相同时才进行分区。

  • 我认为您将“表分区”与“PARTITION BY”混淆了 - 虽然它们的名称相似,但它们没有任何关系。您当然不限于“PARTITION BY”中的一列或表达式,也不需要所谓的“多分区”... (2认同)