【问题标题】:How can I Pivot a table in DB2? [duplicate]如何在 DB2 中透视表? [复制]
【发布时间】:2012-11-27 07:13:54
【问题描述】:

我有下面的表 A,其中对于每个唯一 id,有三个具有某些值的代码。

 ID    Code    Value
---------------------
 11       1       x
 11       2       y
 11       3       z
 12       1       p
 12       2       q
 12       3       r
 13       1       l
 13       2       m
 13       3       n

我有第二张表 B,格式如下:

Id   Code1_Val   Code2_Val    Code3_Val

这里每个唯一 ID 只有一行。我想为第一个表中的每个 id 从第一个表 A 填充第二个表 B。

对于上面的第一个表 A,第二个表 B 应该是:

Id   Code1_Val   Code2_Val    Code3_Val
---------------------------------------------
11       x          y             z
12       p          q             r
13       l          m             n

如何在单个 SQL 查询中实现这一点?

【问题讨论】:

    标签: sql db2


    【解决方案1】:
       select Id,                                              
          max(case when Code = '1' then Value end) as Code1_Val,  
          max(case when Code = '2' then Value end) as Code2_Val,  
          max(case when Code = '3' then Value end) as Code3_Val   
          from TABLEA                                     
          group by Id                                            
    

    【讨论】:

      【解决方案2】:

      如果你的版本没有DECODE(),你也可以用这个:

      INSERT INTO B (id, code1_val, code2_val, code3_val)  
      WITH Ids (id) as (SELECT DISTINCT id
                        FROM A) -- Only to construct list of ids
      
      SELECT Ids.id, a1.value, a2.value, a3.value
      FROM Ids -- or substitute the actual id table
      JOIN A a1
           ON a1.id = ids.id
              AND a1.code = 1
      JOIN A a2
           ON a2.id = ids.id
              AND a2.code = 2
      JOIN A a3
           ON a3.id = ids.id
              AND a3.code = 3
      

      (在我的 V6R1 DB2 实例上工作,并且有一个SQL Fiddle Example)。

      【讨论】:

      • 如果表 A 获得一两个新代码,是否有办法动态执行此操作?
      • 不容易,而且您还需要动态 SQL。我很确定这里有其他地方的例子——本质上,你必须阅读“系统信息”模式表,以这种方式组装查询,然后执行它。鉴于对A 的整体插入应该非常罕见,因此仅更新语句和客户端代码可能会更容易......否则,您将进入 EAV 领域,这(有点)相关但有点不同.
      【解决方案3】:
      SELECT Id,
      max(DECODE(Code, 1, Value)) AS Code1_Val,
      max(DECODE(Code, 2, Value)) AS Code2_Val,
      max(DECODE(Code, 3, Value)) AS Code3_Val
      FROM A
      group by Id
      

      【讨论】:

        【解决方案4】:

        这是SQLFiddle example

        insert into B (ID,Code1_Val,Code2_Val,Code3_Val)
        select Id, max(V1),max(V2),max(V3) from
        (
        select ID,Value V1,'' V2,'' V3 from A where Code=1
        union all
        select ID,'' V1, Value V2,'' V3 from A where Code=2
        union all
        select ID,'' V1, '' V2,Value V3 from A where Code=3
        ) AG
        group by ID
        

        【讨论】:

        • 这应该是专门针对 DB2 的。 SQLFiddle 不支持 DB2...
        • 是的,当然。此 SQL 命令与 SQL-92 兼容,因此所有 DBMS 都必须支持。
        • 但对于任何甚至支持 case 语句的 DBMS 来说,这都不是一个好的 SQL 查询,因为它需要做的工作超出了保证范围。 (分组,在进行 3 次选择并最多调用 3 个不同的列之后...)
        【解决方案5】:

        这是 SQL 查询:

        insert into pivot_insert_table(id,code1_val,code2_val, code3_val) 
        select * from (select id,code,value from pivot_table)
        pivot(max(value) for code in (1,2,3)) order by id ;
        

        【讨论】:

          【解决方案6】:
           WITH Ids (id) as 
           (
            SELECT DISTINCT id FROM A
            )
           SELECT Ids.id, 
           (select sub.value from A sub where Ids.id=sub.id and sub.code=1 fetch first rows only) Code1_Val,
          
           (select sub.value from A sub where Ids.id=sub.id and sub.code=2 fetch first rows only) Code2_Val,
          
           (select sub.value from A sub where Ids.id=sub.id and sub.code=3 fetch first rows only) Code3_Val
           FROM Ids
          

          【讨论】:

            【解决方案7】:

            您想要对数据进行透视。由于 DB2 没有数据透视函数,所以你可以使用 Decode(基本上是一个 case 语句。)

            语法应该是:

            SELECT Id,
               DECODE(Code, 1, Value) AS Code1_Val,
               DECODE(Code, 2, Value) AS Code2_Val,
               DECODE(Code, 3, Value) AS Code3_Val
            FROM A
            

            【讨论】:

            • 依赖于 DB2 的版本;我的 V6R1 (iSeries) 版本没有。
            • 谢谢。您可以更新此语句以使用 case 语句,并避免多个连接。
            • Code3_Val 后面有一个“,”
            猜你喜欢
            • 2018-03-24
            • 2023-04-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-08-31
            • 2020-08-21
            • 2014-12-04
            相关资源
            最近更新 更多