Dans une table comme
id name type info
1 BMW car yes
2 Reno car no
3 IBM electronics no
4 Sony electronics yes
5 Mazda car yes
J'utilise GROUP_CONCAT
Pour obtenir la liste de chaque type
, mais je souhaite séparer la colonne concaténée sur plusieurs colonnes classées par la colonne info
. Ça devrait être quelque chose comme
SELECT type,
GROUP_CONCAT(name) ORDER BY id ASC SEPARATOR ' ') AS list_with_info
GROUP_CONCAT(name) ORDER BY id ASC SEPARATOR ' ') AS list_without_info
FROM table1 GROUP BY type
Comment puis-je introduire WHERE
clause ou utiliser une autre approche pour renvoyer plusieurs colonnes concaténées?
SELECT type,
GROUP_CONCAT( CASE WHEN info = 'yes' THEN name ELSE NULL END
ORDER BY id ASC SEPARATOR ' ') AS list_with_info,
GROUP_CONCAT( CASE WHEN info = 'no' THEN name ELSE NULL END
ORDER BY id ASC SEPARATOR ' ') AS list_without_info
FROM table1
GROUP BY type ;
Testé à SQL-FIDDLE: test-1
Si vous vouliez les résultats en deux rangées au lieu d'un, ce serait plus facile, juste GROUP BY
tous les deux type, info
:
SELECT
type, info,
GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
AS list
FROM table1
GROUP BY type
, info ;
Ceci peut également être utilisé pour fournir le format à une ligne par type souhaité:
SELECT
type,
MIN( CASE WHEN info = 'yes' THEN list END )
AS list_with_info,
MIN( CASE WHEN info = 'no' THEN list END )
AS list_without_info
FROM
( SELECT
type, info,
GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
AS list
FROM table1
GROUP BY type
, info
) AS grp
GROUP BY type ;
Testé à SQL-FIDDLE: test-2
Les deux requêtes ci-dessus bénéficieraient d'un index sur (type, info, name)
Ce qui suit bénéficierait d'un index sur (info, type, name)
:
SELECT
dt.type,
grpy.list AS list_with_info,
grpn.list AS list_without_info
FROM
( SELECT DISTINCT type
FROM table1
) AS dt
LEFT JOIN
( SELECT
type,
GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
AS list
FROM table1
WHERE info = 'yes'
GROUP BY type
) AS grpy
ON grpy.type = dt.type
LEFT JOIN
( SELECT
type,
GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
AS list
FROM table1
WHERE info = 'no'
GROUP BY type
) AS grpn
ON grpn.type = dt.type ;
Testé à SQL-FIDDLE: test-