2017-09-01 2 views
0

Dire que j'ai les données suivantes:SQL: « transposer » un certain nombre de bits/colonnes binaires dans une colonne à plusieurs variables

name is_married has_dog wants_children 
Tom   1  1    1 
Dick   0  1    1 
Harry   0  0    0 

Mais je veux donner les données suivantes:

name description 
Tom is_married 
Tom has_dog 
Tom wants_children 
Dick has_dog 
Dick wants_children 

-à-dire , Je veux placer l'information contenue dans ces différents champs binaires dans une forme où chaque «positif binaire» est montré dans sa propre rangée.

Existe-t-il un moyen de rendre ceci évolutif, s'il y a des centaines de colonnes binaires?

Répondre

0

Voici une routine qui devrait évoluer.

  • Utiliser la table système INFORMATION_SCHEMA pour trouver les noms de colonnes
  • Utilisez un curseur en boucle à travers les noms de colonnes
  • Looping par, créer prepare/execute à exécuter une requête spécifique de trouver les utilisateurs avec cet attribut ET tourner l'attribut (nom de colonne) dans un champ « description »
  • magasin ces valeurs dans une table temporaire pour le nom/Description
  • Sélectionnez la re sultes.

Exemple:

DELIMITER $$ 
CREATE PROCEDURE myproc() 
BEGIN 
    DECLARE sql_stmt varchar(200); 
    DECLARE exit_loop INTEGER DEFAULT 0; 

    DECLARE col_names CURSOR FOR SELECT CONCAT('select name, "', column_name, '" As Description from tbl where ' , column_name, '=1') 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name = 'tbl' 
    and column_name <> 'Name' 
    ORDER BY ordinal_position; 

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE; 

CREATE TEMPORARY TABLE temp (name varchar(200), description varchar(200)); 

OPEN col_names; 

the_loop: LOOP 

    FETCH col_names 
    INTO sql_stmt; 

    IF exit_loop THEN 
     CLOSE col_names; 
     LEAVE the_loop; 
    END IF; 

SET @s = CONCAT('INSERT INTO temp(name, description) ',sql_stmt); 


PREPARE stmt1 FROM @s; 
EXECUTE stmt1; 

END LOOP the_loop; 

SELECT * from temp ORDER BY name; 

DROP TABLE temp; 

END$$ 
DELIMITER ; 

Et les résultats:

mysql> call myproc(); 
+------+----------------+ 
| name | description | 
+------+----------------+ 
| Tom | ismarried  | 
| Tom | hasdog   | 
| Tom | wants_children | 
| Dick | hasdog   | 
| Dick | wants_children | 
+------+----------------+ 
5 rows in set (0.00 sec)