2017-09-16 6 views
0

J'ai regardé les réponses à Mysql query to dynamically convert rows to columns mais je ne pouvais pas le faire fonctionner parce que j'ai besoin de joindre des tables pour obtenir toutes les informations. Pouvez-vous s'il vous plaît m'aider à placer la «question» comme le nom de la colonne comme indiqué ici?Mysql/Mariadb requête pour convertir dynamiquement des lignes en colonnes lors de l'interrogation des données

datestamp   pay  benefits ... career advancement 
--------------------------------------------------------------------- 
2/16/2017 11:55  Somewhat Slightyly  Slightly 
2/16/2017 11:55  Agree  Somewhat  Very 

Les données ressemble à:

id datestamp  survey_col   value 
----------------------------------------------- 
1 2/16/2017 11:55 885457X234X1368SQ001 A3 
1 2/16/2017 11:55 885457X234X1368SQ002 A4 
1 2/16/2017 11:55 885457X234X1368SQ003 A4 
1 2/16/2017 11:55 885457X234X1368SQ004 A3 
1 2/16/2017 11:55 885457X234X1368SQ005 A2 
1 2/16/2017 11:55 885457X234X1368SQ006 A3 
1 2/16/2017 11:55 885457X234X1368SQ007 A4 
1 2/16/2017 11:55 885457X234X1368SQ008 A3 
1 2/16/2017 11:55 885457X234X1368SQ009 A4 
1 2/16/2017 11:55 885457X234X1368SQ010 A1 

J'utilise ce code:

SELECT T.id, T.datestamp, SQ.question, 
     IF(type IN ("K", "N", "S", "T", "Y", "*") AND type NOT IN ("F"), 
     T.value, 
     IF(parent_qid = 0, SA.answer, SA2.answer) 
    ) as answer 
     FROM survey_questions SQ 
     JOIN survey_lookup SL ON SL.qid = SQ.qid 
     JOIN tmp T ON T.survey_col = SL.survey_col 
     LEFT JOIN survey_answers SA ON SA.qid = SQ.qid 
     AND SA.code = T.value 
     AND SA.language = 'en' 
     LEFT JOIN survey_answers SA2 on SA2.qid = SQ.parent_qid 
     AND SA2.code = T.value 
     AND SA2.language = 'en' 
     WHERE SQ.language = 'en' 
     ; 

qui fournit:

id datestamp  question       answer 
---------------------------------------------------------------- 
1 2/16/2017 11:55 Pay         Somewhat 
1 2/16/2017 11:55 Benefits (health plan, leave, etc.) Slightly 
1 2/16/2017 11:55 Career Advancement     Slightly 
1 2/16/2017 11:55 Access to Training     Somewhat 
1 2/16/2017 11:55 Leadership Style     Very 
1 2/16/2017 11:55 Manager/Supervisor Style   Somewhat 
1 2/16/2017 11:55 Please enter comments    The company's policies... 

Ce code a fonctionné lorsque toutes les les données étaient dans une table et je ne devais pas se rejoint.

SET @sql = NULL; 
    SET SESSION GROUP_CONCAT_MAX_LEN = 1000000; -- default is 1024 
    SELECT 
     GROUP_CONCAT(DISTINCT 
     CONCAT(
      'MAX(IF(question = ''', REPLACE(question,"'", "\\'"), ''', answer, NULL)) AS ''', REPLACE(question,"'", "\\'"), '''' 
     ) 
    ) INTO @sql 
     FROM tmp; 

     SET @sql = CONCAT('SELECT row_id, submitdate, ', @sql, ' FROM ', survey_report, ' GROUP BY row_id'); 

     IF DEBUG = 1 THEN 
     SELECT @sql; 
     END IF; 

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

Ceci était une tentative sans la fonction REPLACE (que je voudrais utiliser).

SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
    'MAX(IF(SQ.question = ', '''SQ.question''',' 
     IF(type IN ("K", "N", "S", "T", "Y", "*") AND type NOT IN ("F"), 
     T.value, 
     IF(parent_qid = 0, SA.answer, SA2.answer) 
    ) as answer, NULL)) as answer', '''SQ.question''') 
) INTO @sql 
    FROM survey_questions SQ 
    JOIN survey_lookup SL ON SL.qid = SQ.qid 
    JOIN tmp T ON T.survey_col = SL.survey_col 
    LEFT JOIN survey_answers SA ON SA.qid = SQ.qid 
    AND SA.code = T.value 
    AND SA.language = 'en' 
    LEFT JOIN survey_answers SA2 on SA2.qid = SQ.parent_qid 
    AND SA2.code = T.value 
    AND SA2.language = 'en' 
    WHERE SQ.language = 'en'; 

    SET @sql = CONCAT('SELECT id, datestamp, ', @sql, ' FROM tmp GROUP BY id'); 

    SELECT @sql; 

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

Vous savez probablement déjà que cela s'appelle * pivoter * une table. Vous avez découvert quelle douleur dans le cou c'est dans MySQL. –

+0

Je suis d'accord. J'utilise un logiciel qui est très difficile pour obtenir les données nécessaires. J'utilisais un curseur pour obtenir les données qui étaient horriblement lentes mais j'ai découvert que les syndicats le faisaient beaucoup plus vite. Donc, j'ai utilisé une union pour obtenir les données afin que je puisse créer des jointures. Maintenant, j'essaye de l'obtenir dans un format que je peux utiliser dans un logiciel graphique. J'ai essayé plusieurs choses et cela semble être le meilleur parce qu'il fonctionne en 11 secondes où d'autres solutions j'ai pris 4 minutes. –

+1

C'est l'un de ces moments où SQL est la solution _wrong_ au problème. Ecrire PHP/Java/quel que soit le code pour faire la mise en forme. Utilisez SQL pour fournir les données. –

Répondre

0

Cela a fonctionné mais je n'ai pas voulu créer une autre table.

DROP TEMPORARY TABLE IF EXISTS `tmp2`; 
CREATE TEMPORARY TABLE tmp2 
    SELECT T.id, T.datestamp, SQ.question, 
     IF(type IN ("K", "N", "S", "T", "Y", "*") AND type NOT IN ("F"), 
     T.value, 
     IF(parent_qid = 0, SA.answer, SA2.answer) 
    ) as answer 
     FROM survey_questions SQ 
     JOIN survey_lookup SL ON SL.qid = SQ.qid 
     JOIN tmp T ON T.survey_col = SL.survey_col 
     LEFT JOIN survey_answers SA ON SA.qid = SQ.qid 
     AND SA.code = T.value 
     AND SA.language = 'en' 
     LEFT JOIN survey_answers SA2 on SA2.qid = SQ.parent_qid 
     AND SA2.code = T.value 
     AND SA2.language = 'en' 
     WHERE SQ.language = 'en' 
     ; 

- sélectionnez * à partir de tmp2;

  SET @sql = NULL; 
    SET SESSION GROUP_CONCAT_MAX_LEN = 1000000; -- default is 1024 
    SELECT 
     GROUP_CONCAT(DISTINCT 
     CONCAT(
      'MAX(IF(question = ''', REPLACE(question,"'", "\\'"), ''', answer, NULL)) AS ''', REPLACE(question,"'", "\\'"), '''' 
     ) 
    ) INTO @sql 
     FROM tmp2; 
     SET @sql = CONCAT('SELECT id, datestamp, ', @sql, ' FROM tmp2 GROUP BY id'); 

     SELECT @sql; 

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