简体   繁体   English

在 Oracle 11g 中将 1 列值显示到 3 个不同的列

[英]Display 1 column values to 3 different columns in Oracle 11g

Hey guys i am usnig sql 11g.大家好,我是 sql 11g。 i came across one situation where my table have 1 column like this我遇到了一种情况,我的桌子有 1 列这样

column1
1
john
2000
2
david
4000
4
eon
5000

and i want output to split into 3 different columns like我希望 output 分成 3 个不同的列,例如

id     name     salary
1      john      2000
2      david     3000
4      eon       5000

With just that 1 column in a table you will have dreadful trouble getting the desired output.仅使用表中的 1 列,您将很难获得所需的 output。 In SQL tables are "unordered sets" so there is no guarantee that the data will be extracted in the exact same order you display it above - but to achieve the desired output we must have a reliable order of rows.在 SQL 中,表是“无序集”,因此不能保证数据将按照您在上面显示的完全相同的顺序提取 - 但要实现所需的 output,我们必须有可靠的行顺序。

Assuming there is no other column in that table I would suggest you need to add an ID column like this:假设该表中没有其他列,我建议您需要添加一个 ID 列,如下所示:

alter table mytable
add (
    id NUMBER GENERATED BY DEFAULT AS IDENTITY
    )

+---------+----+
| COLUMN1 | ID |
+---------+----+
| 1       |  1 |
| john    |  2 |
| 2000    |  3 |
| 2       |  4 |
| david   |  5 |
| 4000    |  6 |
| 4       |  7 |
| eon     |  8 |
| 5000    |  9 |
+---------+----+

which (hopefully) will add the information we can then use to help order the output:其中(希望)将添加我们可以用来帮助订购 output 的信息:

In the following we use lag by 1 row, and lead by 1 row to widen the data into 3 column, and then also use modulus of 3 on the id column to select just the wanted rows that have values in all 3 columns:在下面我们使用延迟 1 行,领先 1 行将数据扩展为 3 列,然后在 id 列上使用 3 的模数到 select 只是在所有 3 列中都有值的所需行:

select id, name, salary
from (
    select 
      mod(id,3) AS mod3
    , lag(column1, 1) over(order by id)  as id
    , column1                            as name
    , lead(column1, 1) over(order by id) as salary
    from mytable
)
where mod3 = 2

+----+-------+--------+
| ID | NAME  | SALARY |
+----+-------+--------+
|  1 | john  |   2000 |
|  2 | david |   4000 |
|  4 | eon   |   5000 |
+----+-------+--------+

demo 演示

Schema:架构:

 create table table1 (column1 varchar(50));

 insert into table1
 with cte as (select '1'from dual
 union all
 select 'john' from dual
 union all
 select '2000'from dual
 union all
 select '2'from dual
 union all
 select 'david'from dual
 union all
 select '4000'from dual
 union all
 select '4'from dual
 union all
 select 'eon'from dual
 union all
 select '5000'from dual
 )
  select * from cte

Query:询问:

 with cte as 
 (
     select column1,( ( Row_number()OVER(ORDER BY 1 ) - 1 ) / 3 ) + 1 rn from table1
 )
 , cte2 as
 (
     select column1,rn, row_number()over(partition by NVL(SUBSTR(rn, 0, INSTR(rn, '.')-1), rn) order by rn) rnk  ,NVL(SUBSTR(rn, 0, INSTR(rn, '.')-1), rn)grp
     from cte 
 )
 select max("1")ID,max("2")Name,max("3")Salary from(
 select *  from cte2)
 pivot (max(column1) for rnk in (1,2,3))
 group by grp
 order by grp
 

Output: Output:

ID ID NAME姓名 SALARY薪水
1 1 john约翰 2000 2000
2 2 david大卫 4000 4000
4 4 eon 5000 5000

db<>fiddle here db<> 在这里摆弄

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM