【问题标题】: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])

这看起来是正确的开始方向,但我不知道从哪里开始。

【问题讨论】:

    标签: sql sql-server-2008 greatest-n-per-group


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2016-12-16
      • 2016-02-25
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多