SQL Query引用前面的行

时间:2015-02-17 02:41:32

标签: tsql sql-server-2012

我需要查询帮助。我有一个返回一组简单行的查询。

SELECT      TOP 5 
            ReceivedYTD, 
            InvoicedYTD, 
            OrderedYTD, 
            YearReported, 
            WeekReported 
FROM        Products 
WHERE       ProductId = @ProductId
ORDER BY    YearReported DESC, 
            WeekReported DESC

按周排序的报告列可能有间隙(例如1,2,4,5,6,9 ......)

我想要做的是选择订单序列中前一记录的值的更改。所以在第5周,我可以看到它从第4周开始有什么变化,第4周我会看到第2周的变化,等等。由于顺序可能中断,我不能简单地做一个递归离开加入(或者至少,我不认为我可以。)

2 个答案:

答案 0 :(得分:3)

对于SQL Server 2012 +:

您可以使用LAG功能。

以下是查找之前收到的值的示例,当然其他人的情况也差不多。

SELECT      TOP 5 
            ReceivedYTD, 
            InvoicedYTD, 
            OrderedYTD, 
            YearReported, 
            WeekReported,

-- Relevant part
            LAG(ReceivedYTD)
                OVER (ORDER BY YearReported DESC, WeekReported DESC) AS PreviousReceivedYTD
-- End relevant part

FROM        Products 
WHERE       ProductId = @ProductId
ORDER BY    YearReported DESC, 
            WeekReported DESC

,否则

在你评论回来之前我已经很好地回答了这个问题,所以我就去了。

您必须使用CTE,并通过您正在寻找的行号偏移量将其连接到自身。

WITH CTE AS (
    SELECT      TOP 5 
                RowNumber = ROW_NUMBER() OVER (ORDER BY YearReported DESC, WeekReported DESC)

                ReceivedYTD, 
                InvoicedYTD, 
                OrderedYTD, 
                YearReported, 
                WeekReported,
    FROM        Products 
    WHERE       ProductId = @ProductId
    ORDER BY    YearReported DESC, 
                WeekReported DESC
)

SELECT   CTE.ReceivedYTD, 
         CTE.InvoicedYTD, 
         CTE.OrderedYTD, 
         CTE.YearReported,
         CTE.WeekReported,
         PreviousRow.ReceivedYTD AS PreviousReceivedYTD
FROM CTE
    LEFT OUTER JOIN CTE PreviousRow ON CTE.RowNumber - 1 = PreviousRow.RowNumber

答案 1 :(得分:2)

您可以使用滞后,因为您在2012年:

SELECT      TOP 5 
            ReceivedYTD, 
            LAG(ReceivedYTD, 1, 'NA') OVER (
                PARTITION BY ProductId ORDER BY YearReported DESC, WeekReported DESC) AS RecievedYTD_Last,
            InvoicedYTD, 
            LAG(InvoicedYTD, 1, 'NA') OVER (
                PARTITION BY ProductId ORDER BY YearReported DESC, WeekReported DESC) AS InvoicedYTD_Last,
            OrderedYTD, 
            LAG(OrderedYTD, 1, 'NA') OVER (
                PARTITION BY ProductId ORDER BY YearReported DESC, WeekReported DESC) AS OrderedYTD_Last,
            YearReported, 
            WeekReported,
FROM        Products P
WHERE       ProductId = @ProductId
ORDER BY    YearReported DESC, 
            WeekReported DESC