web-dev-qa-db-fra.com

Comment concaténer des chaînes d'une sous-requête en une seule ligne dans mysql?

J'ai trois tableaux:

table "package"
-----------------------------------------------------
package_id      int(10)        primary key, auto-increment
package_name    varchar(255)
price           decimal(10,2)

table "zones"
------------------------------------------------------
zone_id         varchar(32)    primary key (ex of data: A1, Z2, E3, etc)

table "package_zones"
------------------------------------------------------
package_id     int(10)
zone_id        varchar(32)

Ce que j'essaie de faire est de renvoyer toutes les informations dans le tableau des packages PLUS une liste des zones pour ce package. Je veux que la liste des zones soit triée alphabétiquement et séparée par des virgules.

Donc, la sortie que je recherche est quelque chose comme ça ...

+------------+---------------+--------+----------------+
| package_id | package_name  | price  | zone_list      |
+------------+---------------+--------+----------------+
| 1          | Red Package   | 50.00  | Z1,Z2,Z3       |
| 2          | Blue Package  | 75.00  | A2,D4,Z1,Z2    |
| 3          | Green Package | 100.00 | B4,D1,D2,X1,Z1 |
+------------+---------------+--------+----------------+

Je sais que je pourrais faire quelque chose en PHP avec la couche de présentation pour obtenir le résultat souhaité. Le problème est que je voudrais pouvoir trier zone_list ASC ou DESC ou même utiliser "WHERE zone_list LIKE" "et ainsi de suite. Pour ce faire, j'ai besoin que cela se fasse dans MYSQL.

Je n'ai AUCUNE idée comment même commencer à aborder cela. J'ai essayé d'utiliser une sous-requête, mais elle se plaignait de plusieurs lignes. J'ai essayé de concaténer les multiples lignes en une seule chaîne, mais évidemment MySQL n'aime pas cela.

Merci d'avance.

MISE À JOUR!

Voici la solution pour ceux qui sont intéressés.

SELECT 
    `package`.*,
    GROUP_CONCAT(`zones`.`zone` ORDER BY `zones`.`zone` ASC SEPARATOR ','  )  as `zone_list`
FROM 
    `package`,
    `package_zones`
LEFT JOIN 
    (`zones`,`ao_package_zones`) ON (`zones`.`zone_id` = `package_zones`.`zone_id` AND `package_zones`.`package_id` = `package`.`package_id`)
GROUP BY 
    `ao_package`.`package_id`
34
mrbinky3000

en utilisant la fonction GROUP_CONCAT () et un appel GROUP BY. voici un exemple de requête

SELECT 
   p.package_id,
   p.package_name,
   p.price,
   GROUP_CONCAT(pz.zone_id SEPARATOR ',') as zone_list 
FROM 
   package p 
LEFT JOIN package_zone pz ON p.package_id = pz.package_id 
GROUP BY 
   p.package_id

vous devriez toujours pouvoir commander par zone_id s (ou zone_list), et au lieu d'utiliser LIKE, vous pouvez utiliser WHERE zp.zone_id = 'Z1' ou quelque chose de similaire.

57
GSto