2016-10-05 69 views
2

如何編寫SQL查詢爲以下狀態PL/SQL Oracle查詢的結果

結果必須在PL/SQL查詢:

MY_TABLE和數據是像波紋管:

| sl. no | col1 | col2 | col3 |col4 | col5 ---col30| col41|col42|....col50 
+------ +------+------ +------ +------+ 
| 1001 | 50 | 101 | 12 | 40 | 
| 1002 | 30 | 250 | 80 |  | 
| 1003 | 40 | 150 | 90 |  | 
| 1004 | 50 | 250 | 20 |  | 
| 1005 | 70 | 300 | 30 | 50 | 
| 1006 | 80 | 400 | 

COL1 ,col2,col3,... col30

如果列數據可用,我想檢索col1..to col30對sl.no(其中條件是sl.no)的數據(值)。甲骨文9I 作爲行明智 只有在PL/SQL的Oracle 9i中 結果一樣:

1001 | 50 
1001 | 101 
1001 | 12 
1001 | 40 
1002 | 30 
1002 |250 
1002 | 80 
1003 | 40 
1003 | 150 
1003 | 90 
1004 | 50 
1004 | 250 
1004 | 20 
1005 |70 
1005 |300 
1005 |30 
1005 |50 
1006 |80 
1006 |400 
+0

你想不透明你的表?你爲什麼要/必須使用PL/SQL? –

+0

感謝Aleksej編輯問題。 –

+0

@Alex現有DB是Oracle 9i,語言是SQL –

回答

0
select * 
from (
    select no, decode(rn, 1, col1, 2, col2, 3, col3, 4, col4, 5, col5, ...., 30, col30) col 
    from table_name, (select rownum rn from all_objects where rownum <= 30) 
) 
where col is not null 

select * 
from (
    select no, decode(rn, 1, col1, 2, col2, 3, col3, 4, col4, 5, col5, ...., 30, col30) col 
    from table_name, (select rownum rn from dual connect by rownum <= 30) 
) 
where col is not null 

第二個是更好,但我不記得將它的工作原理在9i或不是

0

爲了不遺漏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。