如何根据特定的顺序选择每组的第一行?
Posted
技术标签:
【中文标题】如何根据特定的顺序选择每组的第一行?【英文标题】:How to select the top row of each group based on a specific ordering? 【发布时间】:2013-01-12 03:13:48 【问题描述】:假设我有一个包含以下数据的表。
表名 [数据]。 PrimaryID:表的主 ID。 ParentID:表引用自身;这是对 PrimaryID 的 FK 约束。DateTime:上次更新的时间。
PrimaryID ParentID Date
1 null 1/1/2013
2 1 1/2/2013
3 1 1/3/2013
4 null 1/4/2013
5 4 1/5/2013
6 null 1/6/2013
我想选择如下所示的结果:
PrimaryID ParentID
3 1
5 4
6 6
对于每个“组”(定义为具有相同 ParentID 和该父项的所有条目),我想选择最近的行,并替换一个空 ParentID(通常表示该行是parent) 具有行自己的 PrimaryID。
我真的不知道从哪里开始生成这样的查询。
我有一个看起来像这样的内部选择:
(SELECT PrimaryID, ISNULL(ParentID, PrimaryID) as ParentID, Date FROM [Data])
这看起来是正确的开始方向,但我不知道从哪里开始。
【问题讨论】:
【参考方案1】:在@ypercube 的帮助下,这样的事情应该可以工作:
SELECT t.PrimaryId, coalesce(t.ParentId,t.PrimaryId) as parent
FROM YourTable t
JOIN (
SELECT coalesce(ParentId, PrimaryId) as parent, Max(DateField) as dtMax
FROM YourTable
GROUP BY coalesce(ParentId, PrimaryId)
) t2 ON coalesce(t.ParentId,t.PrimaryId) = parent AND t.DateField = t2.dtMax
这是更新后的Fiddle。
【讨论】:
这不会总是给出正确的结果:SQL-Fiddle test 您能否详细说明-您的小提琴中哪条记录不正确?我在 5 分钟前添加了 coalesce(t.ParentId,t.PrimaryId) (在回答之前没有在问题中看到)。谢谢。6
已从结果中消失。
我认为你的 Fiddle 已经关闭——你的 4 有一个更高的日期:-)
您错过了重点,日期对组很重要(具有相同 parentId 的行)。看到这个:test-2【参考方案2】:
你可以使用row_number()
:
select primaryid,
coalesce(ParentID, PrimaryID) parentid
from
(
select *,
row_number() over(partition by coalesce(ParentID, PrimaryID)
order by date desc) rn
from yourtable
) src
where rn = 1
见SQL Fiddle with Demo
【讨论】:
以上是关于如何根据特定的顺序选择每组的第一行?的主要内容,如果未能解决你的问题,请参考以下文章