Comment trouver la valeur d'un champ dans une chaine csv avec MySQL

Publié le 11 Janvier 2012

La fonction FIND_IN_SET est l'inverse de la fonction SUBSTRING_INDEX. Elle permet de retourner la position d'un champ dans une chaîne csv.

Par exemple:

SELECT FIND_IN_SET('field3', 'field1,field2,field3,field4');

retourne

3.

Par contre contrairement à SUBSTRING_INDEX où on pouvait spécifier le séparateur à utiliser, FIND_IN_SET ne marche qu'avec le séparateur ','. Ce n'est pas trop grave car on peut toujours utiliser la fonction REPLACE pour remplacer un séparateur quelconque par une virgule.

On peut donc combiner FIND_IN_SET et SUBSTRING_INDEX pour interroger une chaine csv. Imaginons que le format csv est le suivant:

id,nom,prénom,code_postal,ville,téléphone,date_inscription

et que la table data contienne un champ csv qui respecte ce format on va pouvoir extraire tous les noms des données csv avec la requête suivante:

SELECT SUBSTRING_INDEX( SUBSTRING_INDEX(data.csv, ',', FIND_IN_SET('nom', 'id,nom,prénom,code_postal,ville,téléphone,date_inscription'), ',', -1) FROM data;

Par contre c'est un peu long à écrire mais on peut définir une fonction pour simplifier le code:

DELIMITER //
CREATE DEFINER=`root`@`localhost` FUNCTION `csv_value`(csv_value TEXT, field_name VARCHAR(32)) RETURNS VARCHAR(100)
BEGIN
   RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(csv_value, ',', FIND_IN_SET(field_name, 'id,nom,prénom,code_postal,ville,téléphone,date_inscription')), ',', -1);
END
//
DELIMITER ;

et du coup la requête devient:

SELECT csv_value(data.csv, 'nom') FROM data;

Et on peut même l'utiliser dans un WHERE pour ne récupérer que les utilisateurs habitant à Paris:

SELECT csv_value(data.csv, 'nom') AS nom, csv_value(data.csv, 'prénom') AS prenom FROM data WHERE csv_value(data.csv, 'ville) LIKE 'Paris';

C'est presque comme ci on avait une vraie table SQL!

Rédigé par Bliz

Publié dans #MySQL

Repost 0
Commenter cet article