2012-03-19 19 views
0

我如何轉換以下:SQL使用行作爲列

+------+---------+------+ 
| Date | Product | Sold | 
+------+---------+------+ 
| 1/1 | P1  | 100 | 
| 1/1 | P2  | 250 | 
| 1/1 | P3  | 50 | 
| 2/1 | P1  | 170 | 
| 2/1 | P2  | 0 | 
| 2/1 | P3  | 70 | 
+------+---------+------+ 

到一個表是這樣的:

+------+-----+-----+----+ 
| Date | P1 | P2 | P3 | 
+------+-----+-----+----+ 
| 1/1 | 100 | 250 | 50 | 
| 2/1 | 170 | 0 | 70 | 
+------+-----+-----+----+ 

使用SQL?
我知道產品的數量(正好3)。

+0

請查找樞軸。你正在使用哪個數據庫? – 2012-03-19 14:10:36

+2

PIVOT。你使用哪個數據庫? – Randy 2012-03-19 14:10:57

+0

@AmitBhargava我正在使用MySQL – baruch 2012-03-19 14:14:20

回答

5

很多的DBMS提供「支點」和「交叉表報告」的具體支持,但如果你的DBMS沒有,或者如果你喜歡一個解決方案,在各種的DBMS的工作,你可以這樣寫:

SELECT Date, 
     MIN(CASE WHEN Product = 'P1' THEN Sold END) AS "P1", 
     MIN(CASE WHEN Product = 'P2' THEN Sold END) AS "P2", 
     MIN(CASE WHEN Product = 'P3' THEN Sold END) AS "P3" 
    FROM ___insert_table_name_here___ 
GROUP 
    BY Date 
; 

編輯添加:你現在已經提到你正在使用MySQL,其中不是有特殊的支持或交叉表支持,所以上面的查詢是要走的路。

0

如果是SQL Server的2005+:

SELECT 
    Date 
    , [P1] 
    , [P2] 
    , [P3] 
FROM 
(
    SELECT 
     Date 
     , Product 
     , Sold 
    FROM 
     ProductSold 
) AS t1 
PIVOT 
(
    MIN(Sold) 
    FOR Product IN ([P1], [P2], [P3]) 
) AS pvt 
ORDER BY 
    Date ASC; 
0

在MySQL中,如果你有一個未知的列數旋轉,那麼你可以使用prepared statements,你的代碼看起來像這樣(見SQL Fiddle with Demo):

CREATE TABLE Table1 
    (`Date` datetime, `Product` varchar(7), `Sold` int) 
; 

INSERT INTO Table1 
    (`Date`, `Product`, `Sold`) 
VALUES 
    ('2001-01-01 00:00:00', 'P1', 100), 
    ('2001-01-01 00:00:00', 'P2', 250), 
    ('2001-01-01 00:00:00', 'P3', 50), 
    ('2001-02-01 00:00:00', 'P1', 170), 
    ('2001-02-01 00:00:00', 'P2', 0), 
    ('2001-02-01 00:00:00', 'P3', 70) 
; 

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'sum(case when Product = ''', 
     Product, 
     ''' then sold else 0 end) AS ', 
     Product 
    ) 
) INTO @sql 
FROM Table1; 

SET @sql = CONCAT('SELECT Date, ', @sql, ' 
        FROM table1 
        GROUP BY date'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt;