爲了不遺漏pre-11g的方式,你需要做類似的事情:
WITH my_table AS (SELECT 1001 sl_no, 50 col1, 101 col2, 12 col3, 40 col4 FROM dual UNION ALL
SELECT 1002 sl_no, 30 col1, 250 col2, 80 col3, NULL col4 FROM dual UNION ALL
SELECT 1003 sl_no, 40 col1, 150 col2, 90 col3, NULL col4 FROM dual UNION ALL
SELECT 1004 sl_no, 50 col1, 250 col2, 20 col3, NULL col4 FROM dual UNION ALL
SELECT 1005 sl_no, 70 col1, 300 col2, 30 col3, 50 col4 FROM dual UNION ALL
SELECT 1006 sl_no, 80 col1, 400 col2, NULL col3, NULL col4 FROM dual),
dummy AS (SELECT LEVEL lvl
FROM dual
CONNECT BY LEVEL <= 4 -- number of columns to unpivot
),
results AS (SELECT mt.sl_no,
d.lvl,
CASE WHEN d.lvl = 1 THEN 'COL1'
WHEN d.lvl = 2 THEN 'COL2'
WHEN d.lvl = 3 THEN 'COL3'
WHEN d.lvl = 4 THEN 'COL4'
END col_name,
CASE WHEN d.lvl = 1 THEN col1
WHEN d.lvl = 2 THEN col2
WHEN d.lvl = 3 THEN col3
WHEN d.lvl = 4 THEN col4
END col_value
FROM my_table mt
CROSS JOIN dummy d)
SELECT sl_no,
col_name,
col_value
FROM results
WHERE col_value IS NOT NULL
ORDER BY sl_no, lvl;
SL_NO COL_NAME COL_VALUE
---------- -------- ----------
1001 COL1 50
1001 COL2 101
1001 COL3 12
1001 COL4 40
1002 COL1 30
1002 COL2 250
1002 COL3 80
1003 COL1 40
1003 COL2 150
1003 COL3 90
1004 COL1 50
1004 COL2 250
1004 COL3 20
1005 COL1 70
1005 COL2 300
1005 COL3 30
1005 COL4 50
1006 COL1 80
1006 COL2 400
dummy
子查詢用於生成一組與未被轉義的列數相同的行。在你的例子中,它是4.
然後,我們將它交叉連接到表格 - 這意味着表格中的每一行都重複了4次 - 每個列都未重寫。
一旦我們有了這一點,我們說「顯示第一列的第一行上進行unpivot操作,在第二行第二列,第三排第三列,等等......」
我還包括列出相應值來自列名稱的列;我知道你並沒有在你的問題中詢問這些信息,但它通常是必需的,並且很容易生成。
一旦我們有未轉移的列,我們然後刪除任何值爲null。
你想不透明你的表?你爲什麼要/必須使用PL/SQL? –
感謝Aleksej編輯問題。 –
@Alex現有DB是Oracle 9i,語言是SQL –