2014-04-04 28 views
1

我使用的是Oracle 11g,我在这里有一个小问题,希望有人能帮助我。从多行创建一行oracle

当我执行我的查询;

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不是我最强的地方。

谢谢。

+0

你知道永远不会有在台超过3行特定'id'值?如果你添加了第四行,id为120,ver'为4,那么对于预期的输出会有什么影响? –

+0

对于相同的id值,最多会有5行。 – Dr3ko

回答

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,您可以使用情况和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; 
+0

谢谢三,它完全工作,但表格已经改变,现在有另一列;状态,状态可以是'A','C','R'或NULL,我使它可以与CASE和MIN一起工作,但没有得到PIVOT的运气,请问您能多帮一些忙吗? (作为先前的例子,我需要STATUS1,STATUS2,STATUS3,STATUS4,STATUS5,每个都有自己的值,我想使用PIVOT它看起来更亲和更干净)。 – Dr3ko

+0

终于找到了它; (最短(VER)AS VER,MIN(DDATE)AS DATE,MAX(状态)作为版本的状态(1日期1,2日期2,3日期3,4日期4,5日期5)),谢谢! !!!! – Dr3ko

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 
;