将行值转换为列值——SQL PIVOT

发布于 2025-01-02 02:52:03 字数 1026 浏览 1 评论 0原文

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 Returns the following results from table: CowTracking

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

I am trying to get the following results with a PIVOT in SQL

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

This is the code I have so far.

    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

NOTE: The barn_id is a varchar. It will not be possible to change the datatype.

I am not trying to add/multiply/aggregate or whatever. I am simply trying to move the row to a column

How would I go about doing this?
Is this the correct thought process?

Do I even need to use PIVOT?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

欢你一世 2025-01-09 02:52:03

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

使用 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

但本质上,这一切都归结为硬编码 < code>ID 到谷仓


编辑

使其更加稳健

  • 每个结果数据透视表添加 ROW_NUMBER
  • 如果您始终返回固定数量的记录,并且使用 SQL Server,则可以通过向此预先已知数字的

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

As there is no barn1..4 in your tables, you somehow have to replace the ID's with their corresponding barns.

One solution using PIVOT might be like this

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                 

another solution using CASE and GROUP BY could be

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

but in essence, this all boils down to hardcoding an ID to a barn.


Edit

If you always return a fixed number of records, and using SQL Server you might make this a bit more robust by

  • adding a ROW_NUMBER to each result
  • pivot on this upfront known number

SQL Statement

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

Test script

;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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文