引用前几行的 SQL 查询

TSQL Query to reference previous rows

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

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...)

我还想select更改订单序列中上一条记录的值。所以在第 5 周,我可以看到它从第 4 周开始发生了怎样的变化,在第 4 周我会看到它从第 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

对于 SQL 服务器 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