动态旋转到固定数量的列

Dynamically pivot to fixed number of columns

这是我的数据结构

Name       TransID       Amount

Joe        123           56
Joe        124           55
Joe        125           58
Tom        126           31
Tom        127           48

我需要按以下格式报告此数据

Name      Amount1        Amount2

Joe       56             55
Joe       58
Tom       31             48

Joe 在原始数据集中有三个 Amounts,但我需要在视图中有固定数量的列(两列)。因此,Joe 的第三个 Amount 作为新记录插入到视图中。是否可以通过存储过程或创建视图来实现。

将问题分解成更小的步骤。这些是我将采取的步骤:

  • 使用ROW_NUMBER() OVER (PARTITION BY ...):

    Name       TransID       Amount    Row_Number
    
    Joe        123           56        1
    Joe        124           55        2
    Joe        125           58        3
    Tom        126           31        1 
    Tom        127           48        2
    
  • 减 1。

    Name       TransID       Amount    RowNumberStartingWith0
    
    Joe        123           56        0
    Joe        124           55        1
    Joe        125           58        2
    Tom        126           31        0 
    Tom        127           48        1
    
  • 除以2,取余数对2取模:

    Name       TransID       Amount    Result  Remainder
    
    Joe        123           56        0       0
    Joe        124           55        0       1
    Joe        125           58        1       0
    Tom        126           31        0       0 
    Tom        127           48        0       1
    
  • 删除 TransID 列。余数始终为 0 或 1,因此您可以以此为中心:

    Name       Result  AmountForRemainder0 AmountForRemainder1
    
    Joe        0       56                  55
    Joe        1       58
    Tom        0       31                  48
    
  • 现在您删除 Result 列并重命名您的列:

    Name      Amount1        Amount2
    
    Joe       56             55
    Joe       58
    Tom       31             48
    
  • 利润。

试试这个,让我知道。检查其他样本数据also.I我得到了想要的输出。

DECLARE @t TABLE (
    NAME VARCHAR(50)
    ,TransID INT
    ,Amount INT
    )

INSERT INTO @t
VALUES ('Joe',123,56)
    ,('Joe',124,55)
    ,('Joe',125,58)
    ,('Tom',126,31)
    ,('Tom',127,48)
    ,('Tom',128,89)
    ,('Tom',129,90)
    ,('Joe',130,68);

WITH CTE
AS (
    SELECT *
        ,row_number() OVER (
            PARTITION BY NAME ORDER BY amount
            ) rn
    FROM @t
    )
    ,CTE1
AS (
    SELECT NAME
        ,(
            SELECT amount
            FROM cte
            WHERE rn = 1
                AND NAME = a.NAME
            ) [Amount1]
        ,(
            SELECT amount
            FROM cte
            WHERE rn = 2
                AND NAME = a.NAME
            ) [Amount2]
        ,rn
    FROM cte A
    WHERE rn = 1

    UNION ALL

    SELECT b.NAME
        ,a.amount
        ,isnull(c.amount, 0)
        ,a.rn
    FROM CTE1 B

    INNER JOIN CTE A ON a.NAME = b.NAME
        AND a.rn % 2 <> 0
        AND a.rn > 1
        AND b.rn <> a.rn
    OUTER APPLY (
        SELECT Amount
        FROM CTE C
        WHERE NAME = b.NAME
            AND rn % 2 = 0
            AND rn > 2
        ) c

    )
SELECT *
FROM cte1