2014-04-04 27 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 
;