一直在尝试一个场景,我想将返回数据分散到几列而不是冗长的行中
例如
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 |
Run Code Online (Sandbox Code Playgroud)
数据数量并不重要,只要它像上面的格式一样分散即可。我看到了一些有关 Pivot() 的相关文章,但我找不到如何在这种情况下应用它。非常感谢您的帮助,因为我不太擅长 sql。
首先,我将排序后的单元格放入数据透视表中。
select col1, col2 as col from table1
union
select col1, col3 as col from table1
;
Run Code Online (Sandbox Code Playgroud)
然后我提供了哪些行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
)
;
Run Code Online (Sandbox Code Playgroud)
最后我根据文档做了一个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
;
Run Code Online (Sandbox Code Playgroud)
输出:
| 列1 | D | 列2 | 列3 | 彩色4 | 彩色5 | 列6 |
|---|---|---|---|---|---|---|
| 数据头 | 0 | 值01 | 值02 | 值03 | 值04 | 值05 |
| 数据头 | 1 | 值06 | 值07 | 值08 | 值09 | 值10 |
| 数据头 | 2 | 值11 | 值12 | 值13 | 值14 | 值15 |
| 数据头 | 3 | 值16 | (无效的) | (无效的) | (无效的) | (无效的) |
数据定义语言:
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
;
Run Code Online (Sandbox Code Playgroud)
Oracle中的rank over函数用于按顺序对行进行编号。
例如,rank() over (order by col)是一列,其中有从 1 开始的数字,如果按 col 排列该列,它将是 1, 2, 3, ... 如果重新排列行,排名仍将保留根据的值col 列。
因此,我之前的解决方案按字母顺序排列值,无论它们在源表中的位置如何。
如果您想按第一列排序并在最后按相同顺序对第二列排序,则可以使用此内部选择:
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
;
Run Code Online (Sandbox Code Playgroud)
然后生成的选择将如下所示:
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
;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
81 次 |
| 最近记录: |