patternsqlModerate
Multiple "GROUP_CONCAT"s with WHERE clause
Viewed 0 times
withwheremultiplegroup_concatclause
Problem
In a table as
I use
How can I introduce
id name type info
1 BMW car yes
2 Reno car no
3 IBM electronics no
4 Sony electronics yes
5 Mazda car yesI use
GROUP_CONCAT to get the list of each type, but I want to separate the concatenated column to multiple columns categorized by the column info. It should be something likeSELECT 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 typeHow can I introduce
WHERE clause or using other approach to return multiple concatenated columns?Solution
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 ;Tested at SQL-Fiddle: test-1
If you wanted the results in two rows instead of one, it would be easier, just
GROUP BY both type, info:SELECT
type, info,
GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
AS list
FROM table1
GROUP BY type
, info ;This can also be used to provide the one-row-per-type format you want:
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 ;Tested at SQL-Fiddle: test-2
The above two queries would benefit from an index on
(type, info, name)The following would benefit from an index on
(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 ;Tested at SQL-Fiddle: test-3
Code Snippets
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 ;SELECT
type, info,
GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
AS list
FROM table1
GROUP BY type
, info ;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 ;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 ;Context
StackExchange Database Administrators Q#30946, answer score: 14
Revisions (0)
No revisions yet.