问题
options_table
options_id | object_id | option_value
=========================================
1 | 1 | drink
2 | 2 | ice
3 | 1 | bath
4 | 2 | soda
5 | 2 | drink
6 | 3 | ice
7 | 4 | bath
8 | 2 | bath
9 | 1 | storm
object_table
object_id | object_name
=============================
1 | sun
2 | moon
3 | mars
4 | jupiter
The Query
SELECT object_table.object_name GROUP_CONCAT(options_table.option_value ) as object_options
FROM options_table
LEFT JOIN object_table
ON object_table.object_id = options_table.object_id
GROUP BY options_table.object_id
so i get a result like
object_name | object_options
=========================================
moon | ice, soda, drink, bath
sun | drink, bath, storm
mars | ice
jupiter | bath
Lets say the user want all objects that has option "drink" AND option "bath". So i only get this result.
object_name | object_options
=========================================
moon | ice, soda, drink, bath
sun | drink, bath, storm
How do i have to edit the query to get this result?
回答1:
The simplest: http://www.sqlfiddle.com/#!2/1b2e3/5
select obj.object_name,
group_concat(opt.option_value order by opt.options_id) as object_options
from options_table opt
join object_table obj using(object_id)
group by obj.object_id
having sum(opt.option_value in ('drink','bath')) = 2
order by obj.object_name;
Output:
| OBJECT_NAME | OBJECT_OPTIONS |
-------------------------------------
| moon | ice,soda,drink,bath |
| sun | drink,bath,storm |
If you want more ANSI-SQL'y way to do the query, don't rely on MySQLism (boolean/integer duality), use explicit value on SUM instead: http://www.sqlfiddle.com/#!1/14cf4/1
select obj.object_name,
array_agg(opt.option_value order by opt.options_id) as object_options
from options_table opt
join object_table obj using(object_id)
group by obj.object_id, obj.object_name
having sum(case when opt.option_value in ('drink','bath') then 1 end) = 2
order by obj.object_name;
回答2:
Another approach:
SELECT object_name, object_options FROM
(SELECT object_table.object_name,
GROUP_CONCAT(options_table.option_value ) as object_options
FROM options_table
LEFT JOIN object_table
ON object_table.object_id = options_table.object_id
GROUP BY options_table.object_id) t
WHERE FIND_IN_SET('drink', object_options)> 0 AND FIND_IN_SET('bath', object_options)> 0
来源:https://stackoverflow.com/questions/11845963/try-to-match-multiple-values-that-are-in-group-concat