Вы определенно должны быть в состоянии выполнить это упражнение, не выполняя работу, эквивалентную JOIN
в коде приложения, т.е. извлекая все строки из строк заказа и продуктов и просматривая их. Вам не нужно быть мастером SQL, чтобы сделать это. JOIN
для SQL - это то же самое, что цикл для процедурного языка - в том, что оба являются основными языковыми возможностями, которые вы должны знать, как использовать.
Одна ловушка, в которую попадают люди, - это то, что весь отчет должен быть создан в одном SQL-запросе. Не правда! Большинство отчетов не вписываются в прямоугольник, как отмечает Тони Эндрюс. Существует множество сводок, сводок, особых случаев и т. Д., Так что проще и эффективнее извлекать части отчета в отдельных запросах. Аналогично, на процедурном языке вы не пытаетесь выполнить все вычисления в одной строке кода или даже в одной функции (надеюсь).
Некоторые инструменты отчетности настаивают на том, что отчет создается из одного запроса, и у вас нет возможности объединять несколько запросов. Если это так, то вам нужно создать несколько отчетов (и если босс хочет, чтобы это было на одной странице, вам нужно выполнить некоторую вставку вручную).
Чтобы получить список всех заказанных товаров (с названием товара), даты последних трех покупок и комментарии по последнему заказу достаточно просто:
SELECT o.*, l.*, p.*
FROM Orders o
JOIN OrderLines l USING (order_id)
JOIN Products p USING (product_id)
WHERE o.customer_id = ?
ORDER BY o.order_date;
Хорошо бы построчно перебирать результаты, чтобы извлечь даты и комментарии о последних заказах, так как вы все равно выбираете эти строки. Но упростите себе задачу, попросив базу данных вернуть результаты, отсортированные по дате.
Год первой покупки доступен по предыдущему запросу, если вы отсортируете по order_date
и получите результат построчно, у вас будет доступ к первому заказу. В противном случае вы можете сделать это следующим образом:
SELECT YEAR(MIN(o.order_date)) FROM Orders o WHERE o.customer_id = ?;
Сумма покупок за последние 12 месяцев лучше всего рассчитывать отдельным запросом:
SELECT SUM(l.quantity * p.price)
FROM Orders o
JOIN OrderLines l USING (order_id)
JOIN Products p USING (product_id)
WHERE o.customer_id = ?
AND o.order_date > CURDATE() - INTERVAL 1 YEAR;
edit: В другом комментарии вы сказали, что хотите посмотреть, как получить даты трех последних покупок в стандартном SQL:
SELECT o1.order_date
FROM Orders o1
LEFT OUTER JOIN Orders o2
ON (o1.customer_id = o2.customer_id AND (o1.order_date < o2.order_date
OR (o1.order_date = o2.order_date AND o1.order_id < o2.order_id)))
WHERE o1.customer_id = ?
GROUP BY o1.order_id
HAVING COUNT(*) <= 3;
Если вы можете использовать несколько специфичных для поставщика функций SQL, вы можете использовать Microsoft / Sybase TOP
n или MySQL / PostgreSQL LIMIT
:
SELECT TOP 3 order_date
FROM Orders
WHERE customer_id = ?
ORDER BY order_date DESC;
SELECT order_date
FROM Orders
WHERE customer_id = ?
ORDER BY order_date DESC
LIMIT 3;