У меня есть таблица пользователей и таблица заказов . Данные таблицы связаны с помощью ключа user_id . У пользователя есть дата рождения. Необходимо составить запрос для отображения одного случайного пользователя из таблицы users старше 30 лет, который сделал не менее 3 заказов за последние шесть месяцев.

Мне удалось сделать запрос на выборку по возрасту:

SELECT Name from users WHERE(DATEDIFF(SYSDATE(), birthday_at)/365)>30;

Но я не знаю как решить проблему до конца

1
Sergey S. 27 Ноя 2021 в 16:07
Вы пробовали присоединяться к заказам и использовать GROUP BY для получения количества заказов? Вы говорите, что данные связаны с помощью order_id. Неужто это должен быть user_id?
 – 
nnichols
27 Ноя 2021 в 16:24
Да, ошибка моя, общение идет через user_id
 – 
Sergey S.
27 Ноя 2021 в 16:30

1 ответ

Лучший ответ
  • Присоединяйтесь к заказам
    • Принимайте только тех, кто старше 30 лет и с заказами за последние 6 месяцев
      • Группа по пользователю
        • Фильтр по количеству с помощью
          • Ограничить до 1 без сортировки (так как случайное значение)
SELECT usr.Name AS UserName
FROM users AS usr
JOIN orders AS ord
  ON ord.user_id = usr.user_id
WHERE TIMESTAMPDIFF(YEAR, usr.birthday_at, CURDATE()) > 30
  AND ord.order_date BETWEEN DATE_ADD(LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 6+1 MONTH)), INTERVAL 1 DAY)
                         AND LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))
GROUP BY usr.Name
HAVING COUNT(ord.order_id) >= 3
LIMIT 1

Тестовый код для расчета даты

-- previous month, last day
select LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))
| LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) |
| :---------------------------------------------- |
| 2021-10-31                                      |
-- 6 months ago, first day
select DATE_ADD(LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 6+1 MONTH)), INTERVAL 1 DAY)
  
| DATE_ADD(LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 6+1 MONTH)), INTERVAL 1 DAY) |
| :-------------------------------------------------------------------------- |
| 2021-05-01                                                                  |
-- someone's current age
select TIMESTAMPDIFF(YEAR, '2005-11-28', CURDATE())
| TIMESTAMPDIFF(YEAR, '2005-11-28', CURDATE()) |
| -------------------------------------------: |
|                                           15 |

db <> fiddle здесь

1
LukStorms 27 Ноя 2021 в 17:25
@SergeyS. Спасибо. Кстати, я поменял чек за месяцы на BETWEEN. Насколько я понимаю, «последние 6 месяцев» могут не включать текущий месяц.
 – 
LukStorms
27 Ноя 2021 в 17:13