将行值设为列值 - SQL PIVOT

sQu*_*jeW 4 sql pivot

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

    ID  cow_id  barn_id
    --  ------  -------
    19    5       3
    20    5       2
    21    5       9
    22    5       1
Run Code Online (Sandbox Code Playgroud)

我试图在SQL中使用PIVOT获得以下结果

     cow_id  barn1  barn2  barn3  barn4
     ------  -----  -----  -----  -----
       5       3      2      9      1
Run Code Online (Sandbox Code Playgroud)

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

    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
Run Code Online (Sandbox Code Playgroud)

注意:barn_id是varchar.无法更改数据类型.

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

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

我甚至需要使用PIVOT吗?

Lie*_*ers 5

由于barn1..4你的表中没有,你不得不ID用相应的barns 替换' s.

使用的一种解决方案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                 
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

但实际上,这一切都归结为硬编码ID到a 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
Run Code Online (Sandbox Code Playgroud)

测试脚本

;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
Run Code Online (Sandbox Code Playgroud)