将行划分为 SQL 中的特定列 (Oracle)
Divide rows into specific columns in SQL (Oracle)
一直在尝试将 return 数据分散到多列而不是冗长的行中的方案
例如
COL1 | COL2 | COL3
-----------------------------
DATAHEAD | VALUE1 | VALUE9
DATAHEAD | VALUE2 | VALUE10
DATAHEAD | VALUE3 | VALUE11
DATAHEAD | VALUE4 | VALUE12
DATAHEAD | VALUE5 | VALUE13
DATAHEAD | VALUE6 | VALUE14
DATAHEAD | VALUE7 | VALUE15
DATAHEAD | VALUE8 | VALUE16
I want it to spread into 6/n columns dynamically like
this below
COL1 | COL2 | COL3 | COL4 | COL 5 | COL6 |
--------------------------------------------------------------------
DATAHEAD | VALUE1 | VALUE2 | VALUE3 | VALUE4 | VALUE5 |
DATAHEAD | VALUE6 | VALUE7 | VALUE8 | VALUE9 | VALUE10 |
DATAHEAD | VALUE11 | VALUE12 | VALUE13 | VALUE14 | VALUE15 |
DATAHEAD | VALUE16 | Null | Null | Null | Null |
数据的数量无关紧要,只要它像上面的格式一样展开即可。我看到了一些关于 Pivot() 的相关文章,但我找不到如何在这种情况下应用它。非常感谢您的帮助,因为我在 sql.
方面表现不佳
首先,我将经过排序的单元格基数制成一个枢轴 table。
select col1, col2 as col from table1
union
select col1, col3 as col from table1
;
然后我提供了信息,其中行 d
和列 m
将是值。
select
col1,
col,
trunc((rank() over (order by col)-1)/5) as d,
mod(rank() over (order by col)-1,5) as m
from
(
select col1, col2 as col from table1
union
select col1, col3 as col from table1
)
;
最后,我根据documentation做了一个pivot。
select * from
(
select
col1,
col,
trunc((rank() over (order by col)-1)/5) as d,
mod(rank() over (order by col)-1,5) as m
from
(
select col1, col2 as col from table1
union
select col1, col3 as col from table1
)
)
pivot
(
min(col) for m in (0 as COL2,1 as COL3,2 as COL4,3 as COL5,4 as COL6)
)
order by d
;
输出:
COL1
D
COL2
COL3
COL4
COL5
COL6
DATAHEAD
0
VALUE01
VALUE02
VALUE03
VALUE04
VALUE05
DATAHEAD
1
VALUE06
VALUE07
VALUE08
VALUE09
VALUE10
DATAHEAD
2
VALUE11
VALUE12
VALUE13
VALUE14
VALUE15
DATAHEAD
3
VALUE16
(null)
(null)
(null)
(null)
DDL:
CREATE TABLE Table1
("COL1" varchar2(8), "COL2" varchar2(7), "COL3" varchar2(7))
;
INSERT ALL
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE01', 'VALUE09')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE02', 'VALUE10')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE03', 'VALUE11')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE04', 'VALUE12')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE05', 'VALUE13')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE06', 'VALUE14')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE07', 'VALUE15')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE08', 'VALUE16')
SELECT * FROM dual
;
编辑 1:
Oracle中的rank over函数用于按顺序对行进行编号。
例如rank() over (order by col)
是一列,其中有从1开始的数字,如果按列排列,则为1,2,3,...如果重新排列行, rank 还是会保留col 列的值。
所以我以前的解决方案是按字母顺序排列值,而不管它们在源中的位置 table。
如果您想按第一列排序并在最后按相同顺序对第二列进行排序,您可以使用此内部 select:
select
col1,
rank() over (order by col2) as r,
col2 as col
from table1
union
select
col1,
rank() over (order by col2) + (select count(*) from table1) as r,
col3 as col
from table1
;
然后生成的 select 将如下所示:
select * from
(
select
col1,
col,
trunc((r-1)/5) as d,
mod(r-1,5) as m
from
(
select
col1,
rank() over (order by col2) as r,
col2 as col
from table1
union
select
col1,
rank() over (order by col2) + (select count(*) from table1) as r,
col3 as col
from table1
)
)
pivot
(
min(col) for m in (0 as COL2,1 as COL3,2 as COL4,3 as COL5,4 as COL6)
)
order by d
;
一直在尝试将 return 数据分散到多列而不是冗长的行中的方案
例如
COL1 | COL2 | COL3
-----------------------------
DATAHEAD | VALUE1 | VALUE9
DATAHEAD | VALUE2 | VALUE10
DATAHEAD | VALUE3 | VALUE11
DATAHEAD | VALUE4 | VALUE12
DATAHEAD | VALUE5 | VALUE13
DATAHEAD | VALUE6 | VALUE14
DATAHEAD | VALUE7 | VALUE15
DATAHEAD | VALUE8 | VALUE16
I want it to spread into 6/n columns dynamically like
this below
COL1 | COL2 | COL3 | COL4 | COL 5 | COL6 |
--------------------------------------------------------------------
DATAHEAD | VALUE1 | VALUE2 | VALUE3 | VALUE4 | VALUE5 |
DATAHEAD | VALUE6 | VALUE7 | VALUE8 | VALUE9 | VALUE10 |
DATAHEAD | VALUE11 | VALUE12 | VALUE13 | VALUE14 | VALUE15 |
DATAHEAD | VALUE16 | Null | Null | Null | Null |
数据的数量无关紧要,只要它像上面的格式一样展开即可。我看到了一些关于 Pivot() 的相关文章,但我找不到如何在这种情况下应用它。非常感谢您的帮助,因为我在 sql.
方面表现不佳首先,我将经过排序的单元格基数制成一个枢轴 table。
select col1, col2 as col from table1
union
select col1, col3 as col from table1
;
然后我提供了信息,其中行 d
和列 m
将是值。
select
col1,
col,
trunc((rank() over (order by col)-1)/5) as d,
mod(rank() over (order by col)-1,5) as m
from
(
select col1, col2 as col from table1
union
select col1, col3 as col from table1
)
;
最后,我根据documentation做了一个pivot。
select * from
(
select
col1,
col,
trunc((rank() over (order by col)-1)/5) as d,
mod(rank() over (order by col)-1,5) as m
from
(
select col1, col2 as col from table1
union
select col1, col3 as col from table1
)
)
pivot
(
min(col) for m in (0 as COL2,1 as COL3,2 as COL4,3 as COL5,4 as COL6)
)
order by d
;
输出:
COL1 | D | COL2 | COL3 | COL4 | COL5 | COL6 |
---|---|---|---|---|---|---|
DATAHEAD | 0 | VALUE01 | VALUE02 | VALUE03 | VALUE04 | VALUE05 |
DATAHEAD | 1 | VALUE06 | VALUE07 | VALUE08 | VALUE09 | VALUE10 |
DATAHEAD | 2 | VALUE11 | VALUE12 | VALUE13 | VALUE14 | VALUE15 |
DATAHEAD | 3 | VALUE16 | (null) | (null) | (null) | (null) |
DDL:
CREATE TABLE Table1
("COL1" varchar2(8), "COL2" varchar2(7), "COL3" varchar2(7))
;
INSERT ALL
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE01', 'VALUE09')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE02', 'VALUE10')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE03', 'VALUE11')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE04', 'VALUE12')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE05', 'VALUE13')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE06', 'VALUE14')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE07', 'VALUE15')
INTO Table1 ("COL1", "COL2", "COL3")
VALUES ('DATAHEAD', 'VALUE08', 'VALUE16')
SELECT * FROM dual
;
编辑 1:
Oracle中的rank over函数用于按顺序对行进行编号。
例如rank() over (order by col)
是一列,其中有从1开始的数字,如果按列排列,则为1,2,3,...如果重新排列行, rank 还是会保留col 列的值。
所以我以前的解决方案是按字母顺序排列值,而不管它们在源中的位置 table。
如果您想按第一列排序并在最后按相同顺序对第二列进行排序,您可以使用此内部 select:
select
col1,
rank() over (order by col2) as r,
col2 as col
from table1
union
select
col1,
rank() over (order by col2) + (select count(*) from table1) as r,
col3 as col
from table1
;
然后生成的 select 将如下所示:
select * from
(
select
col1,
col,
trunc((r-1)/5) as d,
mod(r-1,5) as m
from
(
select
col1,
rank() over (order by col2) as r,
col2 as col
from table1
union
select
col1,
rank() over (order by col2) + (select count(*) from table1) as r,
col3 as col
from table1
)
)
pivot
(
min(col) for m in (0 as COL2,1 as COL3,2 as COL4,3 as COL5,4 as COL6)
)
order by d
;