简体   繁体   中英

Pivot a table using `group_concat` and `group by`

I have a table about questions and answers with two related columns with ID's. The answers to the questions can be numeric or alphanumeric like this:

╔══════════╦═════════════╦═══════════╦═════════╗
║ 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    ║
╚══════════╩═════════════╩═══════════╩═════════╝

I want to pivot this info so the questions become the columns, and the given answers are placed properly. The result I'm looking for looks like this:

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

I've made my homework and read several Howto pivot in MySQL tutorials and I've come with this:

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

What I get is the following:

╔══════════╦═════════════╦════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ 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?' ║
╚══════════╩═════════════╩════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝

The results retrieved by group_concat are correct but I'd like to, let's say "convert" that string to real columns. This has to be done as dynamically as possible, because in the real table I don't know the exact number of questions and what are they, so I can't hardcode the questions in many group_concat . What am I doing wrong??

THANKS!

PS This in an over simplification of a greater query. If more info needs to be added when new problems arise, I'll add it.

try a query like this. its not tested !

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM