Ниже приведена упрощенная версия моей схемы и данных:
Пользователи:
id | name
1 | Peter
2 | Max
3 | Susan
рестораны:
id | name
1 | Mario
2 | Ali
3 | Alfonzo
4 | BurgerQueen
посуда:
id | name
1 | Burger
2 | Pizza
3 | Salad
users_dishes:
user_id | dish_id
1 | 1
2 | 1
2 | 2
3 | 2
3 | 3
restaurants_dishes:
restaurant_id | dish_id
1 | 2
1 | 3
2 | 1
2 | 3
3 | 1
3 | 2
3 | 3
4 | 1
Итак, у меня есть три объекта: пользователи , рестораны и блюда .
И два отношения многие ко многим .
- Отношение users-dish определяет, что пользователь может есть.
- Отношение рестораны-блюда определяет то, что ресторан может служить.
В качестве ввода у меня есть список идентификаторов пользователей.
Теперь мне нужно найти все рестораны, где все пользователи из списка могут есть то, что им нравится.
Рассмотрим следующий запрос:
select u.name as user, group_concat(distinct r.name) as dishes
from users u
join users_dishes ud on ud.user_id = u.id
join restaurants_dishes rd on rd.dish_id = ud.dish_id
join restaurants r on r.id = rd.restaurant_id
group by u.id
Здесь показаны все рестораны, которые может посетить каждый пользователь.
user | restaurants
Peter | Alfonzo,Ali,BurgerQueen
Max | Alfonzo,Ali,BurgerQueen,Mario
Susan | Alfonzo,Ali,Mario
Итак, мне нужно пересечение множеств.
Вы уже можете видеть, что все три пользователя могут перейти к Альфонсо и Али.
Но Петр не может пойти к Марьяо. И Сьюзен не может пойти в BurgerQueen.
Результат (для идентификаторов пользователя 1,2,3) должен быть:
id | name
2 | Ali
3 | Alfonzo
Для идентификаторов 1, 2 это должно быть
id | restaurant
2 | Ali
3 | Alfonzo
4 | BurgerQueen
Для идентификаторов 2, 3 это должно быть
id | restaurant
1 | Mario
2 | Ali
3 | Alfonzo
Вы можете создать схему и пример данных с помощью следующего сценария SQL:
CREATE TABLE users (id INT AUTO_INCREMENT,name varchar(100),PRIMARY KEY (id));
INSERT INTO users(name) VALUES ('Peter'),('Max'),('Susan');
CREATE TABLE restaurants (id INT AUTO_INCREMENT,name varchar(100),PRIMARY KEY (id));
INSERT INTO restaurants(name) VALUES ('Mario'),('Ali'),('Alfonzo'),('BurgerQueen');
CREATE TABLE dishes (id INT AUTO_INCREMENT,name varchar(100),PRIMARY KEY (id));
INSERT INTO dishes(name) VALUES ('Burger'),('Pizza'),('Salad');
CREATE TABLE users_dishes (user_id INT,dish_id INT,PRIMARY KEY (user_id, dish_id),INDEX (dish_id, user_id));
INSERT INTO users_dishes(user_id, dish_id) VALUES (1,1),(2,1),(2,2),(3,2),(3,3);
CREATE TABLE restaurants_dishes (restaurant_id INT,dish_id INT,PRIMARY KEY (restaurant_id, dish_id),INDEX (dish_id, restaurant_id));
INSERT INTO restaurants_dishes(restaurant_id, dish_id) VALUES (1,2),(1,3),(2,1),(2,3),(3,1),(3,2),(3,3),(4,1);
Я также подготовил SQL-скрипту на db-fiddle.com .
Следует также упомянуть, что мне нужно решение, совместимое с MySQL 5.7 и MariaDB 10.1