Упорядочить по выполнению предложения в SQL

Этот вопрос не касается порядка казней. Речь идет только о порядке.

В стандартном исполнении это:

FROM WHERE GROUP BY HAVING SELECT ORDER BY TOP

EDIT: This question has been more or less the issue of "Does SQL Server apply short circuit evaluation when executing ORDER BY expressions?" The answer is SOMETIMES! I just haven't found a reasonable reason as to why. See Edit #4.

Теперь предположим, что у меня есть такое утверждение:

DECLARE @dt18YearsAgo AS DATETIME = DATEADD(YEAR,-18,GETDATE());
SELECT
  Customers.Name
FROM
  Customers
WHERE
  Customers.DateOfBirth > @dt18YearsAgo
ORDER BY
  Contacts.LastName ASC, --STATEMENT1
  Contacts.FirstName ASC, --STATEMENT2
  (
   SELECT
     MAX(PurchaseDateTime)
   FROM
     Purchases
   WHERE
     Purchases.CustomerID = Customers.CustomerID
  ) DESC --STATEMENT3

Это не реальное утверждение, которое я пытаюсь выполнить, а всего лишь пример. Существует три оператора ORDER BY. Третье утверждение используется только в тех редких случаях, когда фамилия и имя совпадают.

Если нет повторяющихся фамилий, SQL Server не выполняет операторы ORDER BY # 2 и # 3? И, логически, если нет повторяющихся фамилии и имени, SQL Server note выполняет оператор # 3.

Это действительно для оптимизации. Чтение из таблицы покупок должно быть только последним средством. В случае с моим приложением было бы неэффективно читать все «PurchaseDateTime». от & quot; Закупки & quot; группировка по "CustomerID".

Пожалуйста, сохраняйте ответ, связанный с моим вопросом, а не предложение, например, создание индекса для CustomerID, PurchaseDateTime в разделе «Покупки». Вопрос в том, пропускает ли SQL Server ненужные операторы ORDER BY?

Изменить: Очевидно, SQL Server всегда будет выполнять каждый оператор, пока есть одна строка. Даже с одной строкой это даст вам ошибку деления на ноль:

DECLARE @dt18YearsAgo AS DATETIME = DATEADD(YEAR,-18,GETDATE());
SELECT
  Customers.Name
FROM
  Customers
WHERE
  Customers.DateOfBirth > @dt18YearsAgo
ORDER BY
  Contacts.LastName ASC, --STATEMENT1
  Contacts.FirstName ASC, --STATEMENT2
  1/(Contacts.ContactID - Contacts.ContactID) --STATEMENT3

Edit2: По-видимому, это не дает деления на ноль:

DECLARE @dt18YearsAgo AS DATETIME = DATEADD(YEAR,-18,GETDATE());
SELECT
  Customers.Name
FROM
  Customers
WHERE
  Customers.DateOfBirth > @dt18YearsAgo
ORDER BY
  Contacts.LastName ASC, --STATEMENT1
  Contacts.FirstName ASC, --STATEMENT2
  CASE WHEN 1=0
    THEN Contacts.ContactID
    ELSE 1/(Contacts.ContactID - Contacts.ContactID)
  END --STATEMENT3

Ну, первоначальный ответ на мой вопрос - ДА, он выполняется, но приятно то, что я могу прекратить выполнение с надлежащим СЛУЧАЙ КОГДА

Редактировать 3: Мы можем остановить выполнение оператора ORDER BY с надлежащим CASE WHEN. Хитрость, я думаю, заключается в том, чтобы понять, как правильно его использовать CASE WHEN даст мне то, что я хочу, - выполнение короткого замыкания в операторе ORDER BY. Я сравнил План выполнения в SSMS и, в зависимости от оператора CASE WHEN, таблица Закупки не сканируется даже ДАЛЕЕ, КАК это ясно видимый оператор SELECT / FROM:

DECLARE @dt18YearsAgo AS DATETIME = DATEADD(YEAR,-18,GETDATE());
SELECT
  Customers.Name
FROM
  Customers
WHERE
  Customers.DateOfBirth > @dt18YearsAgo
ORDER BY
  Contacts.LastName ASC, --STATEMENT1
  Contacts.FirstName ASC, --STATEMENT2
  CASE WHEN 1=0
    THEN
    (
     SELECT
       MAX(PurchaseDateTime)
     FROM
       Purchases
     WHERE
       Purchases.CustomerID = Customers.CustomerID
    )
    ELSE Customers.DateOfBirth
  END DESC

Изменить 4: Теперь я полностью запутался. Вот пример @Lieven

WITH Test (name, ID) AS
(SELECT 'Lieven1', 1 UNION ALL SELECT 'Lieven2', 2)

SELECT * FROM Test ORDER BY name, 1/ (ID - ID)

Это не дает деления на ноль, что означает, что SQL Server фактически выполняет оценку короткого замыкания в НЕКОТОРЫХ таблицах, особенно тех, которые созданы с помощью команды WITH.

Попытка это с переменной TABLE:

DECLARE @Test TABLE
(
    NAME nvarchar(30),
    ID int
);
INSERT INTO @Test (Name,ID) VALUES('Lieven1',1);
INSERT INTO @Test (Name,ID) VALUES('Lieven2',2);
SELECT * FROM @Test ORDER BY name, 1/ (ID - ID)

даст ошибку деления на ноль.

Ответы на вопрос(3)

Ваш ответ на вопрос