使用`group_concat`和`group by`

时间:2017-04-20 21:46:21

标签: mysql pivot-table group-concat

我有一个关于问题和答案的表格,其中有两个相关的ID列。问题的答案可以是数字或字母数字,如下所示:

╔══════════╦═════════════╦═══════════╦═════════╗
║ visit_id ║ visit_child ║ question  ║ answer  ║
╠══════════╬═════════════╬═══════════╬═════════╣
║   121340 ║      104280 ║ How much? ║ 3       ║
║   121340 ║      104280 ║ How many? ║ 2       ║
║   121340 ║      104280 ║ Why?      ║ Because ║
║   121340 ║      104280 ║ Really?   ║ Yup     ║
║   121485 ║      114190 ║ How much? ║ 5       ║
║   121485 ║      114190 ║ How many? ║ 6       ║
║   121485 ║      114190 ║ Why?      ║ Why not ║
║   121485 ║      114190 ║ Really?   ║ Sure    ║
╚══════════╩═════════════╩═══════════╩═════════╝

我想透视此信息,以便问题成为列,并且给出的答案正确放置。我正在寻找的结果如下:

╔══════════╦═════════════╦═══════════╦═══════════╦═════════╦═════════╗
║ visit_id ║ visit_child ║ How much? ║ How many? ║  Why?   ║ Really? ║
╠══════════╬═════════════╬═══════════╬═══════════╬═════════╬═════════╣
║   121340 ║      104280 ║         3 ║         2 ║ Because ║ Yup     ║
║   121485 ║      114190 ║         5 ║         6 ║ Why not ║ Sure    ║
╚══════════╩═════════════╩═══════════╩═══════════╩═════════╩═════════╝

我已经完成了我的作业,并在MySQL教程中阅读了几个Howto pivot,我已经来了:

SELECT
    infoBase.visit_id,
    infoBase.visit_child,
    GROUP_CONCAT(DISTINCT
        CONCAT('MAX(IF(infoBase.question = \'',question,'\', \'',answer,'\', 0)) AS \'',question,'\'',''), "\n"
    )
FROM    
  visits vi,
  infoBase
WHERE
  vi.id = infoBase.visit_child
GROUP BY
  infoBase.visit_id, infoBase.visit_child

我得到的是以下内容:

╔══════════╦═════════════╦════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ visit_id ║ visit_child ║                                                               GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(infoBase.question = \'',question,'\', \'',answer,'\', 0)) AS \'',question,'\'',''), "\n")                                                               ║
╠══════════╬═════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║   121340 ║      104280 ║ MAX(IF(infoBase.question = 'How much?', '3', 0)) AS 'How much?',MAX(IF(infoBase.question = 'How many?', '2', 0)) AS 'How many?',MAX(IF(infoBase.question = 'Why?', 'Because', 0)) AS 'Why?',MAX(IF(infoBase.question = 'Really?', 'Yup', 0)) AS 'Really?'  ║
║   121485 ║      114190 ║ MAX(IF(infoBase.question = 'How much?', '5', 0)) AS 'How much?',MAX(IF(infoBase.question = 'How many?', '6', 0)) AS 'How many?',MAX(IF(infoBase.question = 'Why?', 'Why not', 0)) AS 'Why?',MAX(IF(infoBase.question = 'Really?', 'Sure', 0)) AS 'Really?' ║
╚══════════╩═════════════╩════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝

group_concat检索到的结果是正确的,但是我想说,将该字符串“转换”为真实列。 这必须尽可能动态地完成,因为在实际表中我不知道问题的确切数量以及它们是什么,所以我不能在许多group_concat中对问题进行硬编码。 我做错了什么?

谢谢!

P.S。这在过度简化更大的查询中。如果在出现新问题时需要添加更多信息,我会添加它。

1 个答案:

答案 0 :(得分:2)

尝试这样的查询。它未经测试!

SELECT
    infoBase.visit_id,
    infoBase.visit_child,
    GROUP_CONCAT(IF(question = 'How much?', answer ,'') SEPARATOR '' ) AS 'How much?' ,
    GROUP_CONCAT(IF(question = 'How many?', answer ,'') SEPARATOR '' ) AS 'How many?' ,
    GROUP_CONCAT(IF(question = 'Why?',      answer ,'') SEPARATOR '' ) AS 'Why?' ,
    GROUP_CONCAT(IF(question = 'Really?',   answer ,'') SEPARATOR '' ) AS 'Really?'
    )
FROM    
  visits vi,
  infoBase
WHERE
  vi.id = infoBase.visit_child
GROUP BY
  infoBase.visit_id;