【发布时间】:2021-10-18 15:38:34
【问题描述】:
我有一个表,我想从中仅检索每组记录中的最新记录,由特定字段中的值标记。
表格内容如下所示:
state date
512 2021-03-09 11:31:38.300
512 2021-03-09 11:31:38.300
512 2021-03-09 11:31:31.693
512 2021-03-09 11:31:31.693
512 2021-03-08 12:49:10.753
512 2021-03-08 12:35:47.357
514 2021-03-08 12:35:01.030
512 2021-03-08 12:33:48.050
514 2021-03-08 12:14:29.537
514 2021-03-08 12:14:29.537
514 2021-03-08 12:14:18.760
512 2021-03-08 12:14:05.597
我想使用OVER 和PARTITION 到SELECT 输出如下:
row state date
1 512 2021-03-09 11:31:38.300
2 512 2021-03-09 11:31:38.300
3 512 2021-03-09 11:31:31.693
4 512 2021-03-09 11:31:31.693
5 512 2021-03-08 12:49:10.753
6 512 2021-03-08 12:35:47.357
1 514 2021-03-08 12:35:01.030
1 512 2021-03-08 12:33:48.050
1 514 2021-03-08 12:14:29.537
2 514 2021-03-08 12:14:29.537
3 514 2021-03-08 12:14:18.760
1 512 2021-03-08 12:14:05.597
如您所见,行按date DESC 排序,state 字段根据row 字段对1 字段中的每个更改进行分组。
目前,我的代码如下所示:
with query as
(
select state, date, row = row_number() over (partition by state order by date desc)
from table
)
select t.*
from table t
inner join query q on t.state = q.state and t.date = q.date
where row = 1
order by t.date desc
不幸的是,这似乎先将记录按state 分组,然后再按date DESC 排序,因此结果只有两个结果集记录,因为state 字段中只有两个不同的值。应该(对于上面的示例数据)有 5 个结果集记录。
如何正确编号分区组?
【问题讨论】:
-
“这似乎是按之前的状态对记录进行分组” 是的,这就是你要求它做的事情。
partition by state。上面只有 2 个不同的状态,所以只有 2 行可以是这些状态的“第一”行。 -
是的,我意识到这一点。我的问题是询问如何对第二个示例块中的行进行分组(分区)。您的评论仅说明了我在问题中指出的内容。
-
那么您在这里的预期结果是什么?如前所述,查询对于您所写的内容正常工作。没有 5 个状态,那你为什么期望 5 行?
-
查看第二个数据表(带有行列)我希望输出对行进行编号。我希望
state字段中的每一组特定值重新开始行编号。如图所示,向下读取行和状态字段,只要state字段从上面的行更改,row编号就会在1处重新开始。 -
啊,经典的间隙和孤岛问题。我添加了几个欺骗目标。
标签: tsql row-number data-partitioning