暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle行到列转换

askTom 2016-08-18
125

问题描述

我在一次采访中被问到这个问题,但无法破解。
我有一个员工表,其值如下
身份证名萨尔
1 Sid 1000
2乔恩·800
3 Ram 600

我希望输出显示如下:

1 2 3
希德·乔恩·拉姆
1000 800 600
即行到列。

我使用case/decode相同。但是他需要不同的答案,因为可能会有更多的列,并且他不想对所有列使用解码。
我在网上搜索了枢轴和其他一些函数,但无法进行可以为我提供此输出的查询。是否可以以上述格式获取输出?如果是,我可以对此查询。

提前谢谢。

专家解答

你正在切换列和行。一种方法是使用pivot和unpivot。

为此,首先将计算出的row_number添加到 “pivot by”。然后列出你的所有列在枢轴聚合:

drop table t purge;
create table t (id int, name varchar2(3), sal int);
    
insert into t values (1, 'Sid', 1000);
insert into t values (2, 'Jon', 800);
insert into t values (3, 'Ram', 600);

with pivoted as (
  select * from (
    select row_number() over (order by id) rn, t.* from t
  )
  pivot  (min(to_char(id)) c1, min(to_char(name)) c2, min(to_char(sal)) c3 
    for rn in (1, 2, 3)
  )
)
  select * from pivoted;

1_C1  1_C2  1_C3  2_C1  2_C2  2_C3  3_C1  3_C2  3_C3  
1     Sid   1000  2     Jon   800   3     Ram   600


注意to_char()。这很重要。最终输出将在单个列中包含数字和字符串。所以你需要规范化为一个类型 (字符串!)。

现在,您可以将所有内容放在一行中,您可以取消这些值。

“但是有多列要展开!” 你说。

没问题。就像我们枢转多个值一样,您可以取消对多个列的透视!

在括号内指定所需的三列的名称。然后再次在括号中提供每行的值。

例如,第一行的值来自枢轴数据中的列1_C1、2_C1和3_C1。所以你想要 (“1_C1”,“2_C1”,“3_C1”)。

把它们放在一起,你会得到:

with pivoted as (
  select * from (
    select row_number() over (order by id) rn, t.* from t
  )
  pivot  (min(to_char(id)) c1, min(to_char(name)) c2, min(to_char(sal)) c3 
    for rn in (1, 2, 3)
  )
)
select c1, c2, c3 from (
  select * from pivoted
)
unpivot ((c1, c2, c3) for val in (
  ("1_C1", "2_C1", "3_C1"),
  ("1_C2", "2_C2", "3_C2"),
  ("1_C3", "2_C3", "3_C3")
));

C1    C2   C3   
1     2    3    
Sid   Jon  Ram  
1000  800  600


注意: 你说过你在10.1。Pivot仅在11g中可用。如果您需要10g解决方案,请查看:

https://asktom.oracle.com/pls/apex/f?p=100:11:::::P11_QUESTION_ID:9470921600346261156
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论