【问题标题】:how to convert a table into another based on each Columns in SQL如何根据SQL中的每个列将一个表转换为另一个表
【发布时间】:2017-06-23 06:24:56
【问题描述】:

我有下表(每个名字都是唯一的):

表 1:

+----+----------+----------------+----------------+----------------+----------------+
| id | workflow | tire1_approver | tire2_approver | tire3_approver | tire4_approver |
+----+----------+----------------+----------------+----------------+----------------+
| 1  | 1        | John           | Mike           | Tom            | Kevin          |
+----+----------+----------------+----------------+----------------+----------------+
| 2  | 2        | Mike           | Andrew         | An             | Bob            | 
+----+----------+----------------+----------------+----------------+----------------+

我需要翻译成下表,一个人可以出现多次:

表 2:

    +----+--------+----------------+-----------+----------------------+
    | ID | Name   | Position       |  Workflow | upper_level_approver |
    +----+--------+----------------+-----------+----------------------+
    | 1  | John   | tire1_approver | 1         | Mike                 |
    +----+--------+----------------+-----------+----------------------+
    | 2  | Mike   | tire2_approver | 1         | Tom                  |
    +----+--------+----------------+-----------+----------------------+
    | 3  | Tom    | tire3_approver | 1         | Kevin                |
    +----+--------+----------------+-----------+----------------------+
    | 4  | Kevin  | tire4_approver | 1         | N/A                  |
    +----+--------+----------------+-----------+----------------------+
    | 5  | Mike   | tire1_approver | 2         | Andrew               |
    +----+--------+----------------+-----------+----------------------+
    | 6  | Andrew | tire2_approver | 2         | An                   |
    +----+--------+----------------+-----------+----------------------+
    | 7  | An     | tire3_approver | 2         | Bob                  |
    +----+--------+----------------+-----------+----------------------+
    | 8  | Bob    | tire4_approver | 2         | N/A                  |
    +----+--------+----------------+-----------+----------------------+

我正在使用 sql developer,我尝试了循环和连接,但无法达到我想要的效果。

TABLE1 和 TABLE2 都在数据库中, 最终我想把它存储在一个存储过程中,当前端对 TABLE1 进行更新时,它也会调用这个过程并自动更新 TABLE2。

请帮忙

【问题讨论】:

    标签: sql oracle join


    【解决方案1】:

    这是一个使用交叉连接(而不是unpivot 运算符)的解决方案。这将适用于旧版本的 Oracle。模拟数据和查询输出与我的其他答案相同(使用unpivot)。

    OP 没有提到null 是否可以在输入表中(在批准者列中)。如果可能,此交叉连接解决方​​案将与 unpivot 解决方案以不同方式处理它们。通过在unpivot 子句中使用可选的include nulls 指令,可以修改unpivot 解决方案以产生与交叉连接相同的结果。或者,如果不应包含 null 值,则可以在交叉连接解决方​​案中使用 where 条件进行处理。

    select id, name, position, workflow,
           lead(name, 1, 'N/A') over (partition by id, workflow order by lvl)
             as upper_level_approver
    from   ( select t.id, 
                    case h.lvl when 1 then t.tire1_approver
                               when 2 then t.tire2_approver
                               when 3 then t.tire3_approver
                               when 4 then t.tire4_approver
                    end
                      as name, 
                    case h.lvl when 1 then 'tire1_approver'
                               when 2 then 'tire2_approver'
                               when 3 then 'tire3_approver'
                               when 4 then 'tire4_approver'
                    end 
                      as position,
                    t.workflow,
                    h.lvl
             from   table1 t
                    cross join
                    ( select level as lvl from dual connect by level <= 4 ) h
        )
    ;
    

    【讨论】:

    • @LukeYang - 从中​​吸取教训:请始终在您的所有帖子、此处和任何其他网站上包含您的 Oracle 版本。如您所见,版本是任何解决方案中的关键细节。
    【解决方案2】:

    根据您的 Oracle 版本,您可能会也可能无法使用以下解决方案。它使用UNPIVOT 运算符,因此需要Oracle 11.2 或更高版本。在早期版本中,您可以使用交叉联接。

       with
         table1 ( id, workflow, tire1_approver, tire2_approver,
                                                tire3_approver, tire4_approver )
           as (
                select 1, 1, 'John', 'Mike'  , 'Tom', 'Kevin' from dual union all
                select 2, 2, 'Mike', 'Andrew', 'An' , 'Bob'   from dual
              )
    -- End of simulated table (for testing; not part of the solution).
    -- SQL query begins BELOW THIS LINE
    select  id, name, position, workflow,
            lead(name, 1, 'N/A') over ( partition by id, workflow order by lvl )
              as upper_level_approver
    from    table1
    unpivot ( name for (position, lvl) in ( tire1_approver as ('tire1_approver', 1),
                                            tire2_approver as ('tire2_approver', 2),
                                            tire3_approver as ('tire3_approver', 3),
                                            tire4_approver as ('tire4_approver', 4)
                                          )
            )
    ;
    
    ID  NAME    POSITION         WORKFLOW  UPPER_LEVEL_APPROVER
    --  ------  --------------  ---------  --------------------
     1  John    tire1_approver          1  Mike  
     1  Mike    tire2_approver          1  Tom   
     1  Tom     tire3_approver          1  Kevin 
     1  Kevin   tire4_approver          1  N/A     
     2  Mike    tire1_approver          2  Andrew
     2  Andrew  tire2_approver          2  An    
     2  An      tire3_approver          2  Bob   
     2  Bob     tire4_approver          2  N/A
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多