#sql
Вопрос:
У меня есть следующие 4 таблицы:
Клиенты:
---- ------------ -----------
| id | first_name | last_name |....
---- ------------ -----------
| 1 | bob | dylan |
| 2 | alice | brown |
| 3 | liv | green |
| 4 | bob | dylan |
---- ------------ -----------
Заказы:
---- -------------
| id | customer_id |....
---- -------------
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
---- -------------
Элемент заказа:
---- ----------- ----------
| id | order_id | fruit_id |....
---- ----------- ----------
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 4 | 4 | 4 |
---- ----------- ----------
Фрукты:
---- --------------
| id | taste_rating | .....
---- --------------
| 1 | 5 |
| 2 | 5 |
| 3 | 2 |
| 4 | 5 |
---- --------------
Я пытаюсь привлечь всех пользователей, которые разделяют то же first_name
самое и last_name
которые заказали фрукты ТОЛЬКО с taste_rating
5
Пример вывода на основе приведенных выше таблиц:
------- ------- ------------ -----------
| u1_id | u2_id | first_name | last_name |
------- ------- ------------ -----------
| 1 | 4 | bob | dylan |
------- ------- ------------ -----------
Это потому, что внутри customers
есть 2 «Боба Дилана», когда, соединяя их с orders
помощью, мы получаем 2 идентификатора 1
amp; 4
, а затем, соединяя их с order_item
помощью , мы получаем fruit_id
1
amp; 4
. Наконец, когда мы получаем плоды из fruit_id
, мы видим, что id
из обоих 1
и 4
имеют taste_rating
из 5.
Я попробовал выполнить следующий запрос:
SELECT customers.id, customers.first_name, customers.last_name
FROM customers
INNER JOIN orders ON orders.customer_id = customers.id
INNER JOIN order_item ON order_item.order_id = orders.id
INNER JOIN fruits ON fruits.id = order_item.fruits_id
WHERE fruits.id IN (
SELECT fruits.id
FROM fruits
GROUP BY fruits.id
HAVING taste_rating = 5)
GROUP BY customers.first_name, customers.last_name, customers.id, fruits.taste_rating
Это дает мне всех пользователей, у которых были заказы только с помощью a taste_rating = 5
, хотя я не уверен, как получить только тех, у кого такие же first_name
amp; last_name
Ответ №1:
Когда вы не группируете по customers.id .
Тогда количество уникальных идентификаторов клиентов не будет равно 1 для клиентов, у которых более 1 идентификатора.
(или разные люди с одним и тем же именем)
Поскольку они заказали только 5 оценок, некоторые проверки условного агрегирования могут помочь в этом.
SELECT MIN(cust.id) AS u1_id , MAX(cust.id) AS u2_id , cust.first_name , cust.last_name --, COUNT(DISTINCT cust.id) AS TotalUniqCustId --, COUNT(DISTINCT fruit.id) AS TotalFruitId --, MAX(CASE WHEN fruit.taste_rating != 5 THEN 1 ELSE 0 END) AS HadBeside5 --, COUNT(DISTINCT CASE WHEN fruit.taste_rating = 5 THEN cust.id END) AS TotalCustHad5 FROM customers AS cust INNER JOIN orders ON orders.customer_id = cust.id INNER JOIN order_item AS itm ON itm.order_id = orders.id LEFT JOIN fruits AS fruit ON fruit.id = itm.fruit_id GROUP BY cust.first_name, cust.last_name HAVING COUNT(DISTINCT cust.id) >= 2 -- same name users AND MAX(CASE WHEN fruit.taste_rating != 5 THEN 1 ELSE 0 END) = 0 AND COUNT(DISTINCT CASE WHEN fruit.taste_rating = 5 THEN cust.id END) >= 2 ;
u1_id | u2_id | first_name | last_name |
---|---|---|---|
1 | 4 | боб | дилан |
db<>скрипка здесь
Комментарии:
1. Это дает мне всех пользователей, у которых есть хотя бы один рейтинг
5
, а не КАЖДЫЙ рейтинг5
. Это также не дает мне идентификаторы пользователей двух пользователей с одинаковыми именами.2. @bobdylan01 Проверьте обновление. Теперь со скрипкой.
3. Это все еще не дает мне
id
клиентов, у которых одно и то же имя. Пример выходной таблицы в моем вопросе — это то, как должен выглядеть результат. Меня не волнуют итоги4. Хорошо, теперь с идентификаторами и без итогов.