在mysql中将多行放入多列

时间:2013-03-25 08:22:29

标签: mysql sql pivot

考虑下表

Name                                      Null?    Type
----------------------------------------- -------- --------------
PRODID                                             NUMBER
PRODNAME                                           VARCHAR2(50)

 Name                                      Null?    Type
 ----------------------------------------- -------- --------------
 PRODID                                             NUMBER
 PROPID                                             NUMBER
 PRONAME                                            VARCHAR2(100)
 PROVALUE                                           VARCHAR2(100)

样本数据如下

 select * from prodmas;
    PRODID PRODNAME
---------- --------------
       101 Surf
       102 Ariel
 select * from prodprop
 /

PRODID     PROPID PRONAME   PROVALUE                     
------ ---------- -----------------------------------------------
   101       1001 Price     100
   101       1002 color     Blue
   101       1003 Agent     AV
   102       1001 Price     95
   102       1002 Color     Orange
.....

像这样的普通联接查询

 select prodname,provalue
 from prodmas pm
 inner join prodprop pp
 on pm.prodid = pp.prodid
 /
PRODNAME                                           PROVALUE
-------------------------------------------------- -----------
Surf                                               100
Surf                                               Blue
Surf                                               AV
Ariel                                              95
Ariel                                              Orange

但预期的输出应该是这样的

Surf    100   Blue   AV 
Ariel    95   Orange AV
.......
希望我更清楚

2 个答案:

答案 0 :(得分:4)

SELECT  a.ProdID,
        a.ProdName,
        MAX(CASE WHEN b.ProName = 'Price' THEN b.ProValue ELSE NULL END) Price,
        MAX(CASE WHEN b.ProName = 'Color' THEN b.ProValue ELSE NULL END) Color,
        MAX(CASE WHEN b.ProName = 'Agent' THEN b.ProValue ELSE NULL END) Agent
FROM    prodmas a
        LEFT JOIN prodprop b
            ON .prodID = b.prodID
GROUP   BY a.ProdID, a.ProdName

如果PRONAME未知值,则首选动态SQL,因此查询不需要进行其他更改。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(case when PRONAME = ''',
      PRONAME,
      ''' then PROVALUE end) AS ',
      PRONAME
    )
  ) INTO @sql
FROM prodprop;

SET @sql = CONCAT('SELECT   a.ProdID,
                            a.ProdName, ', @sql, ' 
                  FROM    prodmas a
                          LEFT JOIN prodprop b
                              ON a.prodID = b.prodID
                  GROUP   BY a.ProdID, a.ProdName');

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

上述查询的输出是相同的:

╔════════╦══════════╦═══════╦════════╦════════╗
║ PRODID ║ PRODNAME ║ PRICE ║ COLOR  ║ AGENT  ║
╠════════╬══════════╬═══════╬════════╬════════╣
║    101 ║ Surf     ║   100 ║ Blue   ║ AV     ║
║    102 ║ Ariel    ║    95 ║ Orange ║ (null) ║
╚════════╩══════════╩═══════╩════════╩════════╝

答案 1 :(得分:-2)

如果您可以静态地指定所有内容,则可以使用prodprop上的联接为要检索的每个属性执行此操作:

SELECT p.prodname, 
    prop1001.provalue AS Price, 
    prop1002.provalue AS Color, 
    prop1003.provalue AS Agent
FROM prodmas p
LEFT OUTER JOIN prodprop prop1001 ON p.prodid = prop1001.prodid 
    AND prop1001.propid=1001
LEFT OUTER JOIN prodprop prop1002 ON p.prodid = prop1002.prodid
    AND prop1002.propid=1002
LEFT OUTER JOIN prodprop prop1003 ON p.prodid = prop1003.prodid
    AND prop1003.propid=1003

否则,您将不得不求助于动态SQL来创建自定义查询,或按原样返回属性表,并在前端执行格式化。