Я изучаю SQL. При ответе на вопрос * Сколько всего заказов было размещено для региона с наибольшим объемом продаж total_amt_usd? для следующей схемы:
(Я не уверен в диалекте, но думаю, что это Postgres
)
Я придумал следующее решение, и мне интересно, совершаю ли я плохую практику (поскольку официальное решение сильно отличается).
SELECT
r.name AS region_name,
COUNT(*) AS orders_n
FROM ORDERS AS o
INNER JOIN accounts AS a
ON o.account_id = a.id
INNER JOIN sales_reps as s
ON a.sales_rep_id = s.id
INNER JOIN region as r
ON s.region_id = r.id
GROUP BY 1
ORDER BY SUM(o.total_amt_usd) DESC
LIMIT 1;
Официальное решение:
WITH t1 AS (
SELECT r.name region_name, SUM(o.total_amt_usd) total_amt
FROM sales_reps s
JOIN accounts a
ON a.sales_rep_id = s.id
JOIN orders o
ON o.account_id = a.id
JOIN region r
ON r.id = s.region_id
GROUP BY r.name),
t2 AS (
SELECT MAX(total_amt)
FROM t1)
SELECT r.name, COUNT(o.total) total_orders
FROM sales_reps s
JOIN accounts a
ON a.sales_rep_id = s.id
JOIN orders o
ON o.account_id = a.id
JOIN region r
ON r.id = s.region_id
GROUP BY r.name
HAVING SUM(o.total_amt_usd) = (SELECT * FROM t2);
* Это часть упражнения 4.13 великого онлайн-курс пользователя Udacity.
1 ответ
Ваше решение, честно говоря, звучит великолепно и лучше, чем предлагаемое, по удобочитаемости, длине и, вероятно, производительности (хотя никогда не бывает слишком легко узнать сложность движка на основе того, как они оптимизируют запросы). И в моем понимании смысловой разницы нет.
Некоторые придирки: я делаю запрос по-другому и использую имя столбца, а не индекс в GROUP BY
SELECT r.name AS region_name,
COUNT(*) AS orders_n
FROM orders AS o
INNER JOIN accounts AS a
ON o.account_id = a.id
INNER JOIN sales_reps AS s
ON a.sales_rep_id = s.id
INNER JOIN region AS r
ON s.region_id = r.id
GROUP BY region_name
ORDER BY SUM(o.total_amt_usd) DESC
LIMIT 1;
Механизм оптимизации запросов в равной степени оптимизирует ваш запрос и сам определит порядок соединения, если вы используете предложение WHERE. Так что вы также можете написать это так
SELECT r.name AS region_name,
COUNT(*) AS orders_n
FROM orders AS o,
accounts AS a,
sales_reps AS s,
region AS r
WHERE o.account_id = a.id
AND a.sales_rep_id = s.id
AND s.region_id = r.id
GROUP BY region_name
ORDER BY SUM(o.total_amt_usd) DESC
LIMIT 1;