Порядок выполнения исключения запроса SQL для SELECT / HAVING - PullRequest
0 голосов
/ 03 мая 2020

Я понимаю, что порядок или исполнение выглядит следующим образом

FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP

из этого SO ответа , а также Документация Microsoft

Однако в моем запросе ниже столбец total построен на лету, который позже используется в предложении having. Это будет означать, что having выполняет ПОСЛЕ выбора, а не раньше, потому что столбец 'total' не существует в таблице orders.

Я неправильно понимаю или просто что-то упустил?

Запрос

select customer_id, 
        sum(CASE
        WHEN product_name = 'A' THEN 1
        WHEN product_name = 'B' THEN 1
        WHEN product_name = 'C' THEN -1
        ELSE 0 END
        ) as total  
from Orders
group by customer_id
having total > 1;

Таблица заказов

+------------+-------------+--------------+
|   order_id | customer_id | product_name |
+------------+-------------+--------------+
|         10 |           1 | A            |
|         20 |           1 | B            |
|         30 |           1 | D            |
|         40 |           1 | C            |
|         50 |           2 | A            |
|         60 |           3 | A            |
|         70 |           3 | B            |
|         80 |           3 | D            |
|         90 |           4 | C            |
+------------+-------------+--------------+

Результат

+-------------+-------+
| customer_id | total |
+-------------+-------+
|           3 |     2 |
+-------------+-------+

1 Ответ

2 голосов
/ 03 мая 2020

То, что вы описали, НЕ является «порядком исполнения». Это порядок определения области действия для идентификаторов, определенных в запросе.

Это говорит о том, что идентификатор, определенный в from, известен в пунктах ниже. Аналогично, идентификатор, определенный в select, равен , а не , распознанному в having. Я должен отметить, что многие базы данных позволяют предложению having использовать псевдонимы в предложении having. SQL Сервер не является одним из них.

SQL является описательным языком, а не процедурным языком. Это означает, что запрос описывает набор результатов. В нем не указаны шаги, использованные для генерации результата. Компилятор и оптимизатор создают план выполнения, который не похож на исходный запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...