Sql server 如何获取具有未知偏移量的先前有序行的键?

Sql server 如何获取具有未知偏移量的先前有序行的键?,sql-server,Sql Server,我正在与一家ERP合作,该ERP将其零售额和与该销售相关的任何折扣作为单独的行存储在同一张表中 产品线由0线类型标识,而折扣线由6线类型标识,忠诚度折扣由7线类型标识 不幸的是,折扣记录与折扣适用的产品线没有任何直接关系 我需要提取这些数据,对于折扣线,提供它所适用的产品线的密钥 折扣行6和7总是出现在0线型之后,并且可以通过序列号来识别。例如,在下表中,第二行和第三行是第一行的折扣,因为它们的线型为6和7,在线型0之后 我需要我的结果如下所示: Id LineType Sequ

我正在与一家ERP合作,该ERP将其零售额和与该销售相关的任何折扣作为单独的行存储在同一张表中

产品线由0线类型标识,而折扣线由6线类型标识,忠诚度折扣由7线类型标识

不幸的是,折扣记录与折扣适用的产品线没有任何直接关系

我需要提取这些数据,对于折扣线,提供它所适用的产品线的密钥

折扣行6和7总是出现在0线型之后,并且可以通过序列号来识别。例如,在下表中,第二行和第三行是第一行的折扣,因为它们的线型为6和7,在线型0之后

我需要我的结果如下所示:

Id     LineType     SequenceNumber    Description              ProductLineId
---------------------------------------------------------------------
1      0            1                 Product A                NULL
2      6            2                 Discount on Product A    1
3      7            3                 Loyalty Discount         1
4      0            4                 Product B                NULL
5      0            5                 Product C                NULL
6      6            6                 Discount on Product C    5
我知道我可以使用滞后函数,但是偏移量未知,因为可能会有更多的折扣。我目前正在使用一个类似于下面的光标,但速度非常慢。下面是相同的概念,但它针对数据设置了一个标志,而不是记录的ID:

OPEN SalesLines
FETCH NEXT FROM SalesLines INTO @SourceKey, @HeaderSourceKey, @IsMarkedDownFlag, @LineSequenceNumber, @RetailLineTypeId

WHILE @@FETCH_STATUS = 0
BEGIN
  IF @RetailLineTypeId = 1 OR @CurrentHeaderSourceKey != @HeaderSourceKey
  BEGIN
    SET @CurrentIsMarkedDownFlag = @IsMarkedDownFlag
    SET @CurrentHeaderSourceKey = @HeaderSourceKey
  END
  ELSE
  BEGIN
    IF @CurrentIsMarkedDownFlag != @IsMarkedDownFlag
    BEGIN
      UPDATE @RawData
      SET IsMarkedDown = @CurrentIsMarkedDownFlag
      WHERE SourceKey = @SourceKey
    END
  END

这只是一个快速的尝试,但我认为它提供了所需的输出。欢迎任何改进

;WITH products
AS
(SELECT Id, SequenceNumber
FROM    sales
WHERE   LineType = 0)

SELECT  s.Id, s.LineType, s.SequenceNumber, s.Description, p.Id AS ProductLineId
FROM    sales s
        LEFT JOIN products p 
            ON p.SequenceNumber = 
                (SELECT MAX(SequenceNumber) FROM products p2 
                   WHERE p2.SequenceNumber < s.SequenceNumber)
                AND s.LineType <> 0

这只是一个快速的尝试,但我认为它提供了所需的输出。欢迎任何改进

;WITH products
AS
(SELECT Id, SequenceNumber
FROM    sales
WHERE   LineType = 0)

SELECT  s.Id, s.LineType, s.SequenceNumber, s.Description, p.Id AS ProductLineId
FROM    sales s
        LEFT JOIN products p 
            ON p.SequenceNumber = 
                (SELECT MAX(SequenceNumber) FROM products p2 
                   WHERE p2.SequenceNumber < s.SequenceNumber)
                AND s.LineType <> 0

您可以使用外部应用来实现这一点:


在SequenceNumber和线型上创建索引可以加快速度。

您可以使用外部应用来实现这一点:

在SequenceNumber和LineType上创建索引可以加快速度。

查找类型为0且小于下一行0的下一行

已编辑

查找类型为0且小于下一行0的下一行


编辑

完美!我的后脑勺里有一个外贴,但没有进一步看。太好了!我的后脑勺里有一个外部的应用程序,但没有进一步研究它。