添加包含每个组中上一行ID的列

时间:2015-10-14 10:28:45

标签: sql sql-server sql-server-2008 sql-server-2005 sql-server-2008-r2

我想添加一个包含每个组中上一行ID的列。

样品:

Product       ID
Orange        1
Orange        2
Orange        3
Orange        4
Apple         5
Apple         6
Apple         7
Grapes        8
Grapes        9

期望的输出:

Product       ID
Orange        1
Orange        1
Orange        2
Orange        3
Apple         5
Apple         5
Apple         6
Grapes        8
Grapes        8

谢谢!

3 个答案:

答案 0 :(得分:0)

如果正确理解了您的问题您可以尝试以下方式:

SELECT DISTINCT Product, 
                MIN(Id) OVER (PARTITION BY Product) Id
FROM #Products

UNION ALL

SELECT Product, Id
FROM (
    SELECT Product, 
           Id, 
           ROW_NUMBER() OVER (PARTITION BY Product ORDER BY ID DESC) AS rn
FROM #Products
)x
WHERE rn <> 1
ORDER BY Id

<强>输出

Product Id
Orange  1
Orange  1
Orange  2
Orange  3
Apple   5
Apple   5
Apple   6
Grapes  8
Grapes  8

答案 1 :(得分:0)

我会使用outer apply或相关子查询来处理此问题。通常,如果没有先前的ID,NULL将是完全可以接受的:

select s.*, s2.id as previd
from sample s outer apply
     (select top 1 s2.id
      from sample s2
      where s2.product = s.product and s2.id < s.id
      order by s2.id desc
     ) s2 ;

在这种情况下,您似乎想要第一个id。这是一个修复:

select s.*, coalesce(s2.id, smin.minid) as previd
from sample s outer apply
     (select top 1 s2.id
      from sample s2
      where s2.product = s.product and s2.id < s.id
      order by s2.id desc
     ) s2 outer apply
     (select min(s2.id) as minid
      from sample s2
      where s2.product = s.product
     ) mins;

当然,在SQL Server 2012+中,您将使用ANSI标准函数lag()

select s.*,
       coalesce(lag(s.id) over (partition by s.product order by s.id),
                min(s.id) over (partition by s.product)
               ) as sprev
from sample s;

答案 2 :(得分:0)

851

PS:如果它是2012或更高版本,那么它支持PostgreSQL的ROWS / RANGE。 PS2:您可以使用SQLFiddle将示例数据作为代码而不是纯文本。