2012-03-19 20 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;