【问题标题】:Duplicate row based on other columns values基于其他列值的重复行
【发布时间】:2019-10-09 05:16:51
【问题描述】:

我正在从表格中提取订单,每个订单都有状态和提前期。 订单从状态传递的确切顺序如下: “已放置”>“已确认”>“已发货”

行看起来像

id_order    dsc_status  lead
1           placed      8
1           confirmed   5
1           shipped     1

我需要返回:

id_order    dsc_status  lead     iter
    1           placed      8    0
    1           placed      8    1
    1           placed      8    2
    1           placed      8    3
    1           confirmed   5    0
    1           confirmed   5    1
    1           confirmed   5    2
    1           confirmed   5    3
    1           confirmed   5    4
    1           shipped     1    0
    1           shipped     1    1

逻辑: 在示例中,放置和确认之间的提前期差异为 3,因此我重复放置行 4 次(基于 0 的计数),确认 > 发货时相同。 对于已发货,我们会重复,就像后面跟着一个lead = 0 的虚构状态,这意味着我们重复了 2 次,请检查结果。

【问题讨论】:

  • “lead”中存储的内容。您说的是时间,但时间单位是什么?这是 24 小时制的一天中的一个小时吗?

标签: sql-server split rows


【解决方案1】:

您可以使用 CURSOR 来获得所需的输出-

DECLARE @id_order INT
DECLARE @id_Status_order INT
DECLARE @dsc_statue VARCHAR(100)
DECLARE @lead INT

DECLARE @LoopCount INT

DECLARE @TmpTable TABLE
(
    id_order INT,    dsc_status VARCHAR(200),  lead INT,     iter INT
)

DECLARE @id_order_prev INT
DECLARE @dsc_statue_prev VARCHAR(100)
DECLARE @lead_prev INT

DECLARE db_cursor CURSOR FOR 
SELECT id_order,Status_Order,dsc_status,lead
FROM 
(
    SELECT id_order,dsc_status,lead, 
    CASE 
        WHEN dsc_status = 'placed' THEN 1 
        WHEN dsc_status = 'confirmed' THEN 2
        WHEN dsc_status = 'shipped' THEN 3
    END Status_Order
    FROM your_table
)A
ORDER BY 1,2

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @id_order,@id_Status_order ,@dsc_statue,@lead

WHILE @@FETCH_STATUS = 0  
BEGIN

    IF @id_order_prev IS NULL
    BEGIN

        SET @id_order_prev = @id_order
        SET @dsc_statue_prev = @dsc_statue
        SET @lead_prev = @lead

    END

    ELSE
    BEGIN
        SET @LoopCount  = 0 

        WHILE @LoopCount <= CASE WHEN @id_order_prev = @id_order THEN ABS(@lead_prev-@lead) ELSE @lead_prev END
        BEGIN

           INSERT INTO @TmpTable (id_order,dsc_status,lead,iter)
           VALUES (@id_order_prev,@dsc_statue_prev,@lead_prev,@LoopCount)

           SET @LoopCount = @LoopCount + 1
        END

        SET @id_order_prev = @id_order
        SET @dsc_statue_prev = @dsc_statue
        SET @lead_prev = @lead
    END



    FETCH NEXT FROM db_cursor INTO @id_order,@id_Status_order ,@dsc_statue,@lead

    IF  @@FETCH_STATUS <> 0
    BEGIN 

        SET @LoopCount = 0
        WHILE @LoopCount <= @lead
        BEGIN

           INSERT INTO @TmpTable (id_order,dsc_status,lead,iter)
           VALUES (@id_order_prev,@dsc_statue_prev,@lead_prev,@LoopCount)

           SET @LoopCount = @LoopCount + 1
        END

    END
END 



CLOSE db_cursor  
DEALLOCATE db_cursor 


SELECT * 
FROM @TmpTable
ORDER BY 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-15
    • 2019-03-08
    • 2020-11-01
    • 2018-05-08
    • 1970-01-01
    • 2019-09-30
    • 2019-09-18
    • 1970-01-01
    相关资源
    最近更新 更多