[英]Divide rows into specific columns in SQL (Oracle)
一直在嘗試一個場景,我想將返回數據分散到幾列而不是冗長的行中
例如
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 中不是那么好。
首先,我在 pivot 表中創建了一個已排序的單元格庫。
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
)
;
最后,我按照文檔做了一個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 |
---|---|---|---|---|---|---|
數據頭 | 0 | VALUE01 | VALUE02 | VALUE03 | VALUE04 | VALUE05 |
數據頭 | 1 | VALUE06 | VALUE07 | VALUE08 | VALUE09 | 價值10 |
數據頭 | 2 | 價值11 | 價值12 | 價值13 | 價值14 | 價值15 |
數據頭 | 3 | 價值16 | (無效的) | (無效的) | (無效的) | (無效的) |
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
;
Oracle 中 function 的排名用於按順序對行進行編號。
例如, rank() over (order by col)
是一列,其中有從 1 開始的數字,如果按 col 排列該列,它將是 1,2,3,... 如果重新排列行,根據 col 列,排名仍將保留該值。
因此,我之前的解決方案按字母順序排列值,而不管它們在源表中的位置如何。
如果您想按第一列排序並在最后以相同的順序對第二列排序,您可以使用這個內部 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
;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.