PL / SQL ORACLE查询为Result

时间:2016-10-05 07:41:28

标签: oracle plsql

如何为以下条件编写SQL查询

结果必须在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

如果col数据可用,我想要对sl.no(其中condition为sl.no)检索col1..to col30数据(值)。 Oracle 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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

要取消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次 - 每个列都有一行未被转换。

一旦我们有了这个,我们说“显示第一行的第一列,第二行的第二列,第三行的第三列,等......”

我还添加了一个列,列出了相应值来自的列名;我知道你没有在你的问题中询问这些信息,但这通常是必需的,而且很容易制作。

一旦我们忽略了列,我们就会删除任何null值。