Execução de ordem por cláusula em SQL

Esta questão não é sobre a ordem das execuções. É sobre apenas o ORDER BY.

Na execução padrão é:

DEONDEGRUPO PORTENDOSELECIONARORDENAR PORTOPO

EDIT: Esta questão tem sido mais ou menos a questão de "O SQL Server aplica avaliação de curto-circuito ao executar expressões ORDER BY?"A resposta é às vezes! Eu apenas não encontrei uma razão razoável do porquê. Veja Editar # 4.

Agora suponha que eu tenha uma declaração como esta:

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

Esta não é a afirmação real que estou tentando executar, mas apenas um exemplo. Existem três declarações ORDER BY. A terceira declaração é usada apenas para casos raros em que o sobrenome e o primeiro nome coincidem.

Se não houver sobrenomes duplicados, o SQL Server não executa instruções ORDER BY # 2 e # 3? E, logicamente, se não houver sobrenome e nome em duplicado, o SQL Server observa a instrução # 3.

Isso é realmente para otimização. A leitura da tabela de compras deve ser apenas um último recurso. No caso do meu aplicativo, não seria eficiente ler cada "PurchaseDateTime" do agrupamento "Compras" por "CustomerID".

Por favor, mantenha a resposta relacionada à minha pergunta e não uma sugestão como a criação de um índice para CustomerID, PurchaseDateTime em Compras. A verdadeira questão é: o SQL Server ignora instruções ORDER BY desnecessárias?

Edit: Aparentemente, o SQL Server sempre executará todas as instruções, desde que haja uma linha. Mesmo com uma linha, isso resultará em um erro de divisão por zero:

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: Aparentemente, isso não dá divisão por zero:

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

Bem, a resposta original para a minha pergunta é sim, ele executa, mas o que é bom é que eu posso parar de executar com um bom caso quando

Edit 3: Podemos interromper a execução de uma instrução ORDER BY com um CASE QUANDO QUANDO. O truque, eu acho, é descobrir como usá-lo corretamente. CASO QUANDO me dará o que eu quero, que uma execução de curto-circuito em uma instrução ORDER BY. Eu comparei o Plano de Execução no SSMS e, dependendo da instrução CASE WHEN, a tabela de Compras não é escaneada, embora seja uma declaração SELECT / FROM claramente visível:

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

Edit 4: Agora estou completamente confuso. Aqui está um exemplo de @Lieven

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

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

Isso não resulta em divisão por zero, o que significa que o SQL Server faz, de fato, uma avaliação de curto-circuito em algumas tabelas, especificamente aquelas criadas com o comando WITH.

Tentando isso com uma variável 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)

resultará em uma divisão por erro zero.

questionAnswers(3)

yourAnswerToTheQuestion