Avoding CT и прочие грехи?

Я изучаю 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 ответ
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;

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *