【问题标题】:Making row values into column values -- SQL PIVOT将行值变成列值——SQL PIVOT
【发布时间】:2012-02-03 03:40:03
【问题描述】:

SQL 从表中返回以下结果:CowTracking

    ID  cow_id  barn_id
    --  ------  -------
    19    5       3
    20    5       2
    21    5       9
    22    5       1

我正在尝试使用 SQL 中的 PIVOT 获得以下结果

     cow_id  barn1  barn2  barn3  barn4
     ------  -----  -----  -----  -----
       5       3      2      9      1

这是我到目前为止的代码。

    SELECT *
    FROM 
    (
        SELECT TOP 4 *
        FROM CowTracking
            WHERE cow_id = 5
    ) AS DataTable
    PIVOT
    (
        MIN(barn_id) **IDK what function to use and which column to use it on**
        FOR ID  ??<---**NOT SURE**
        IN 
        (
        [barn1], [barn2], [barn3], [barn4]
        )
    ) AS PivotTable


    ERRORS: Error converting data type nvarchar to int
            The incorrect value "barn1" is supplied in the PIVOT operator

注意:barn_id 是一个 varchar。无法更改数据类型。

我不是想加/乘/聚合或其他什么。我只是想将行移到一列

我该怎么做呢? 这是正确的思考过程吗?

我什至需要使用 PIVOT 吗?

【问题讨论】:

    标签: sql pivot


    【解决方案1】:

    由于您的表中没有barn1..4,因此您必须以某种方式将ID 替换为对应的barns。

    使用PIVOT 的一个解决方案可能是这样的

    SELECT  cow_id
            , [19] as [barn1]
            , [20] as [barn2]
            , [21] as [barn3]
            , [22] as [barn4]
    FROM    (       
                SELECT  *
                FROM    DataTable
                PIVOT   (   MIN(barn_id)
                            FOR ID IN ([19], [20], [21], [22])
                        ) AS PivotTable
            ) q                 
    

    使用CASEGROUP BY 的另一种解决方案可能是

    SELECT  cow_id
            , [barn1] = SUM(CASE WHEN ID = 19 THEN barn_id END)
            , [barn2] = SUM(CASE WHEN ID = 20 THEN barn_id END)
            , [barn3] = SUM(CASE WHEN ID = 21 THEN barn_id END)
            , [barn4] = SUM(CASE WHEN ID = 22 THEN barn_id END)
    FROM    DataTable
    GROUP BY
            cow_id
    

    但本质上,这一切都归结为将ID 硬编码为barn


    编辑

    如果您总是返回固定数量的记录,并且使用 SQL Server,您可能会通过

    • 为每个结果添加ROW_NUMBER
    • 关注这个预先知道的数字

    SQL 语句

    SELECT  cow_id  
            , [barn1] = SUM(CASE WHEN rn = 1 THEN barn_id END)
            , [barn2] = SUM(CASE WHEN rn = 2 THEN barn_id END)
            , [barn3] = SUM(CASE WHEN rn = 3 THEN barn_id END)
            , [barn4] = SUM(CASE WHEN rn = 4 THEN barn_id END)
    FROM    (
                SELECT  cow_id
                        , rn = ROW_NUMBER() OVER (ORDER BY ID)
                        , barn_id
                FROM    DataTable       
            ) q
    GROUP BY
            cow_id
    

    测试脚本

    ;WITH DataTable (ID, cow_id, barn_id) AS (
        SELECT * FROM (VALUES 
            (19, 5, 3)
            , (20, 5, 2)
            , (21, 5, 9)
            , (22, 5, 1)
        ) AS q (a, b, c)        
    )
    SELECT  cow_id  
            , [barn1] = SUM(CASE WHEN rn = 1 THEN barn_id END)
            , [barn2] = SUM(CASE WHEN rn = 2 THEN barn_id END)
            , [barn3] = SUM(CASE WHEN rn = 3 THEN barn_id END)
            , [barn4] = SUM(CASE WHEN rn = 4 THEN barn_id END)
    FROM    (
                SELECT  cow_id
                        , rn = ROW_NUMBER() OVER (ORDER BY ID)
                        , barn_id
                FROM    DataTable       
            ) q
    GROUP BY
            cow_id
    

    【讨论】:

    • 您的第一个建议是正确的。起初我很担心,因为 ID 总是会改变。但后来我宣布了一个新列并将其设置为始终为 1 - 4。然后我能够完成它。谢谢队友,非常感谢。我花了一点时间来理解这个概念
    • @sQuijeW - 不客气。如果这回答了您的问题,您可以将其标记为 (How does accepting an answer work?)
    猜你喜欢
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多