Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于根据行的唯一值将行转换为列的SQL select语句_Sql_Oracle11g_Pivot - Fatal编程技术网

用于根据行的唯一值将行转换为列的SQL select语句

用于根据行的唯一值将行转换为列的SQL select语句,sql,oracle11g,pivot,Sql,Oracle11g,Pivot,我在oracle数据库中名为training的表中有以下数据 id dept usr tt em sk sal 10 2 user1 ttl1 eml2 skl1 100 10 2 user1 ttl1 eml2 skl2 200 10 2 user1 ttl1 eml2 skl3 300 10 2 user1 ttl1 eml2 skl4 400 20 3 user2 ttl3 eml4 skl1 1

我在oracle数据库中名为training的表中有以下数据

id dept  usr   tt   em     sk    sal
10  2   user1  ttl1  eml2  skl1  100
10  2   user1  ttl1  eml2  skl2  200
10  2   user1  ttl1  eml2  skl3  300
10  2   user1  ttl1  eml2  skl4  400
20  3   user2  ttl3  eml4  skl1  150
30  4   user3  ttl6  eml8  skl1  100
30  4   user3  ttl6  eml8  skl2  200
30  4   user3  ttl6  eml8  skl3  300
30  4   user3  ttl6  eml8  skl4  400
30  4   user3  ttl6  eml8  skl5  150    
...
and many more rows
有没有办法用sql select语句获得以下结果

id  dept usr    tt   em   sk1   sal1 sk2  sal2 sk3  sal3 sk4  sal4 sk5  sal5 sk6  sal6
10  2    user1  ttl1 eml2 skl1  100  skl2 200  skl3 300  skl4 300   
20  3    user2  ttl3 eml4 skl1  150
30  4    user3  ttl6 eml8 skl1  100  skl2 200  skl3 300  skl4 400  skl5 150
...

获得结果的简单方法是使用带有CASE表达式的聚合函数。我将首先查询数据,并使用窗口功能
row_number()
根据
id
dept
usr
为数据组生成唯一序列:

select id,
  dept,
  usr,
  tt,
  em,
  max(case when seq = 1 then sk end) sk1,
  max(case when seq = 1 then sal end) sal1,
  max(case when seq = 2 then sk end) sk2,
  max(case when seq = 2 then sal end) sal2,
  max(case when seq = 3 then sk end) sk3,
  max(case when seq = 3 then sal end) sal3,
  max(case when seq = 4 then sk end) sk4,
  max(case when seq = 4 then sal end) sal4,
  max(case when seq = 5 then sk end) sk5,
  max(case when seq = 5 then sal end) sal5,
  max(case when seq = 6 then sk end) sk6,
  max(case when seq = 6 then sal end) sal6
from
(
  select id, dept, usr, tt, em, sk, sal,
    row_number() over(partition by id, dept, usr
                      order by sk) seq
  from yourtable
) d
group by id, dept, usr, tt, em;

由于您使用的是Oracle 11g,因此可以实现PIVOT和UNPIVOT函数来获得结果。UNPIVOT将用于将
sk
sal
的多列转换为多行,然后您可以使用PIVOT将其转换为最终结果。语法类似于:

with cte as
(
  select id, dept, usr, tt, em, sk, 
    to_char(sal) sal,
    row_number() over(partition by id, dept, usr
                      order by sk) seq
  from yourtable
)
select 
  id, dept, usr, tt, em,
  sk1, sal1, sk2, sal2,
  sk3, sal3, sk4, sal4,
  sk5, sal5, sk6, sal6
from
(
  select id, dept, usr, tt, em, 
    lower(col)||to_char(seq) col, value
  from cte
  unpivot
  (
    value
    for col in (sk, sal)
  ) u
) d
pivot
(
  max(value)
  for col in ('sk1' as sk1, 'sal1' as sal1, 
              'sk2' as sk2, 'sal2' as sal2, 
              'sk3' as sk3, 'sal3' as sal3,
              'sk4' as sk4, 'sal4' as sal4,
              'sk5' as sk5, 'sal5' as sal5,
              'sk6' as sk6, 'sal6' as sal6)
) ;
看。两者都给出了一个结果:

| ID | DEPT |   USR |   TT |   EM |  SK1 | SAL1 |    SK2 |   SAL2 |    SK3 |   SAL3 |    SK4 |   SAL4 |    SK5 |   SAL5 |    SK6 |   SAL6 |
|----|------|-------|------|------|------|------|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|
| 10 |    2 | user1 | ttl1 | eml2 | skl1 |  100 |   skl2 |    200 |   skl3 |    300 |   skl4 |    400 | (null) | (null) | (null) | (null) |
| 20 |    3 | user2 | ttl3 | eml4 | skl1 |  150 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |
| 30 |    4 | user3 | ttl6 | eml8 | skl1 |  100 |   skl2 |    200 |   skl3 |    300 |   skl4 |    400 |   skl5 |    150 | (null) | (null) |

是否提前知道skl的数量?最多可以有10个skl。我只显示到sk6,但可以扩展到SK10如何在结果中添加另一列,将每个用户的sal中的所有值相加?@sian非常简单,请参阅第一个版本和pivot版本。我还有一个问题-不是将SK1 SAL1..SK2 SAL2…等放在两个单独的列中,有没有一种方法可以将这两个列值合并为一个列来显示?@sian您需要看看如何使用LISTAGGfunction@blufeet出于某种原因,它无法识别LISTAGG