簡體   English   中英

將行划分為 SQL (Oracle) 中的特定列

[英]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
;

編輯1:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM