从多行oracle中创建一行

时间:2014-04-04 00:14:45

标签: sql oracle select row

我正在使用Oracle 11g,我在这里遇到一些问题,希望有人可以帮助我。

当我执行查询时;

SELECT * 
FROM myTable;

结果是:

     ID     |     VER     |     DATE
 -----------+-------------+--------------
    120     |      1      |   01/03/14
    120     |      2      |   02/03/14
    120     |      3      |   04/03/14

    110     |      1      |   01/03/14

    130     |      1      |   02/03/14
    130     |      2      |   11/03/14

我需要这样的东西:

    ID   |   VER   |   DATE   |   VER2   |   DATE2   |   VER3   |   DATE3
---------+---------+----------+----------+-----------+----------+-----------
   120   |    1    | 01/03/14 |    2     | 02/03/14  |     3    | 04/03/14
   110   |    1    | 01/03/14 |          |           |          | 
   130   |    1    | 02/03/14 |    2     | 11/03/14  |          | 

同时在某些时候我需要SUM或休息DATE3 - DATE2和/或DATE2 - DATE1

在这个论坛上有点新手,还不知道它是如何运作的,希望我能清楚自己。

有人告诉我使用CASEDECODE但老实说SQL并不是我最强的领域。

感谢。

2 个答案:

答案 0 :(得分:2)

您可以使用数据透视功能

在Oracle 11g中执行此操作
 WITH TABLE1(ID, VER, DDATE) AS (
 select 120     ,      1      ,   '01/03/14' from dual union all
 select 120     ,      2      ,   '02/03/14' FROM DUAL UNION ALL
 select 120     ,      3      ,   '04/03/14' from dual union all
 select 110     ,      1      ,   '01/03/14' FROM DUAL UNION ALL
 select 130     ,      1      ,   '02/03/14' FROM DUAL UNION ALL
 SELECT 130     ,      2      ,   '11/03/14' FROM DUAL) 
 ------------
 ---- End of Data
 ------------
 SELECT * 
  FROM TABLE1
PIVOT (MIN(VER) AS VER, MIN(DDATE) FOR VER IN (1 as DATE1, 2 as DATE2, 3 as DATE3, 4 as DATE4, 5 as DATE5));

在oracle的早期版本中,您可以使用case和min

 WITH TABLE1(ID, VER, DDATE) AS (
 select 120     ,      1      ,   '01/03/14' from dual union all
 select 120     ,      2      ,   '02/03/14' FROM DUAL UNION ALL
 select 120     ,      3      ,   '04/03/14' from dual union all
 select 110     ,      1      ,   '01/03/14' FROM DUAL UNION ALL
 select 130     ,      1      ,   '02/03/14' FROM DUAL UNION ALL
 SELECT 130     ,      2      ,   '11/03/14' FROM DUAL) 
 ------------
 ---- End of Data
 ------------
 SELECT ID, 
        MIN(CASE WHEN VER = 1 THEN VER ELSE NULL END) AS VER1,
        MIN(CASE WHEN VER = 1 THEN DDATE ELSE NULL END) AS DDATE1,
        MIN(CASE WHEN VER = 2 THEN VER ELSE NULL END) AS VER2,
        MIN(CASE WHEN VER = 2 THEN DDATE ELSE NULL END) as DDATE2,
        MIN(CASE WHEN VER = 3 THEN VER ELSE NULL END) AS VER3,
        MIN(CASE WHEN VER = 3 THEN DDATE ELSE NULL END) as DDATE3,
        MIN(CASE WHEN VER = 4 THEN VER ELSE NULL END) AS VER5,
        MIN(CASE WHEN VER = 4 THEN DDATE ELSE NULL END) as DDATE4,
        MIN(CASE WHEN VER = 5 THEN VER ELSE NULL END) AS VER6,
        min(case when ver = 5 then DDATE else null end) as DDATE5
  FROM TABLE1
group by id;

两个案例的输出都是

|  ID | VER1 |   DDATE1 |   VER2 |   DDATE2 |   VER3 |   DDATE3 |   VER5 | DDATE4 |   VER6 | DDATE5 |
|-----|------|----------|--------|----------|--------|----------|--------|--------|--------|--------|
| 120 |    1 | 01/03/14 |      2 | 02/03/14 |      3 | 04/03/14 | (null) | (null) | (null) | (null) |
| 110 |    1 | 01/03/14 | (null) |   (null) | (null) |   (null) | (null) | (null) | (null) | (null) |
| 130 |    1 | 02/03/14 |      2 | 11/03/14 | (null) |   (null) | (null) | (null) | (null) | (null) |

对于您的表格,您可以使用

 SELECT * 
  FROM <your table_name>
PIVOT (MIN(VER) AS VER, MIN(DDATE) FOR VER IN (1 as DATE1, 2 as DATE2, 3 as DATE3, 4 as DATE4, 5 as DATE5));

 SELECT ID, 
        MIN(CASE WHEN VER = 1 THEN VER ELSE NULL END) AS VER1,
        MIN(CASE WHEN VER = 1 THEN DDATE ELSE NULL END) AS DDATE1,
        MIN(CASE WHEN VER = 2 THEN VER ELSE NULL END) AS VER2,
        MIN(CASE WHEN VER = 2 THEN DDATE ELSE NULL END) as DDATE2,
        MIN(CASE WHEN VER = 3 THEN VER ELSE NULL END) AS VER3,
        MIN(CASE WHEN VER = 3 THEN DDATE ELSE NULL END) as DDATE3,
        MIN(CASE WHEN VER = 4 THEN VER ELSE NULL END) AS VER5,
        MIN(CASE WHEN VER = 4 THEN DDATE ELSE NULL END) as DDATE4,
        MIN(CASE WHEN VER = 5 THEN VER ELSE NULL END) AS VER6,
        min(case when ver = 5 then DDATE else null end) as DDATE5
  FROM <your_table_name>
group by id;

答案 1 :(得分:0)

只要你只有一小部分有限的版本,you could do it this way (SQL Fiddle)

  WITH VER1 AS (SELECT * FROM version_data WHERE version = 1)
     , VER2 AS (SELECT * FROM version_data WHERE version = 2)
     , VER3 AS (SELECT * FROM version_data WHERE version = 3)
     , VER4 AS (SELECT * FROM version_data WHERE version = 4)
     , VER5 AS (SELECT * FROM version_data WHERE version = 5)
SELECT DISTINCT(t.version_id) AS "VERSION_ID",
       ver1.version AS "VER1",
       ver1.version_date AS "VER1_DATE",
       ver2.version AS "VER2",
       ver2.version_date AS "VER2_DATE",
       ver3.version AS "VER3",
       ver3.version_date AS "VER3_DATE",
       ver4.version AS "VER4",
       ver5.version_date AS "VER4_DATE",
       ver5.version AS "VER5",
       ver5.version_date AS "VER5_DATE"
  FROM version_data t
  LEFT JOIN VER1 ver1 ON ver1.version_id = t.version_id
  LEFT JOIN VER2 ver2 ON ver2.version_id = t.version_id
  LEFT JOIN VER3 ver3 ON ver3.version_id = t.version_id
  LEFT JOIN VER4 ver4 ON ver4.version_id = t.version_id
  LEFT JOIN VER5 ver5 ON ver5.version_id = t.version_id
 ORDER BY t.version_id
;