База данных MySQL содержит две таблицы с отношением "один ко многим": один пользователь может иметь множество настроек:
Users:
id username password
--------------------------
1 Bob 123
2 Alice abc
...
Settings:
id user_id key value
-----------------------------
1 1 color blue // Bobs settings...
2 1 theme xy
3 1 size 5
4 2 size 5 // Alices settings...
Проблема: как найти всех пользователей с color == blue AND size == 5
?
Используя LEFT JOIN
нет проблем найти пользователей с одним свойством:
SELECT users.id FROM users LEFT JOIN settings ON users.id = settings.user_id WHERE settings.key = 'color' AND settings.value = 'blue'
Однако это не работает при поиске двух настроек за раз?
Можно ли решить это с помощью одного заявления? Каков наиболее эффективный способ запроса этих данных?
Один метод использует агрегацию и having
:
select s.user_id
from settings s
where (key, value) in ( ('color', 'blue'), ('size', '5') )
group by s.user_id
having count(*) = 2;
Это предполагает, что нет повторяющихся настроек (если это так, вам нужно будет использовать count(distinct)
).