2017-06-22 82 views
1
每列

我有以下表(每名是唯一的):如何将表格转换成另一种基于在SQL

表1:

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

我需要把它翻译如下表成一个人可以出现不止一次:

TABLE2:

+----+--------+----------------+-----------+----------------------+ 
    | 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开发人员,我甲肝E尝试循环和加入,但无法达到我想要的。

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

请帮助

回答

0

根据您的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 
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 
    ) 
; 
+0

这工作完美,谢谢! –

+0

@LukeYang - 从这里得到的教训:请始终在您的所有帖子,这里和任何其他网站中包含您的Oracle版本。如您所见,该版本是任何解决方案中的关键细节。 – mathguy

相关问题