ti-enxame.com

Referindo-se a um alias de coluna em uma cláusula WHERE

SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120

Eu recebo

"nome da coluna inválida daysdiff".

Maxlogtm é um campo de data e hora. São as pequenas coisas que me deixam louco.

138
user990016
SELECT
   logcount, logUserID, maxlogtm,
   DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE ( DATEDIFF(day, maxlogtm, GETDATE() > 120)

Normalmente você não pode se referir a alias de campo na cláusula WHERE. (Pense nisso como todo o SELECT incluindo aliases, é aplicado após a cláusula WHERE.)

Mas, como mencionado em outras respostas, você pode forçar o SQL a tratar SELECT para ser manipulado antes da cláusula WHERE. Isso geralmente é feito com parênteses para forçar a ordem lógica de operação ou com uma Expressão de tabela comum (CTE):

Parêntese/Subselecionar:

SELECT
   *
FROM
(
   SELECT
      logcount, logUserID, maxlogtm,
      DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
   FROM statslogsummary   
) as innerTable
WHERE daysdiff > 120

Ou veja a resposta de Adam para uma versão CTE do mesmo.

158
Jamie F

Se você quiser usar o alias em sua cláusula WHERE, você precisa envolvê-lo em uma sub seleção, ou CTE :

WITH LogDateDiff AS
(
   SELECT logcount, logUserID, maxlogtm
      , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
   FROM statslogsummary
)
SELECT logCount, logUserId, maxlogtm, daysdiff
FROM LogDateDiff
WHERE daysdiff > 120
69
Adam Wenger

Se você não quiser listar todas as suas colunas no CTE, outra maneira de fazer isso seria usar outer apply :

select
    s.logcount, s.logUserID, s.maxlogtm,
    a.daysdiff
from statslogsummary as s
    outer apply (select datediff(day, s.maxlogtm, getdate()) as daysdiff) as a
where a.daysdiff > 120
8
Roman Pekar

A maneira mais eficaz de fazer isso sem repetir seu código é usar TENDO em vez de ONDE

SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
HAVING daysdiff > 120
8
Pascal

Que tal usar uma subconsulta (isso funcionou para mim no Mysql)?

SELECT * from (SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary) as 'your_alias'
WHERE daysdiff > 120
5
Shekhar Joshi

Ter trabalhos no MySQL de acordo com a documentação:

A cláusula HAVING foi incluída no SQL porque a palavra-chave WHERE não pôde ser usada com funções agregadas.

4
roier.rdz

Você pode se referir ao alias de coluna, mas precisa defini-lo usando CROSS/OUTER APPLY:

SELECT s.logcount, s.logUserID, s.maxlogtm, c.daysdiff
FROM statslogsummary s
CROSS APPLY (SELECT DATEDIFF(day, s.maxlogtm, GETDATE()) AS daysdiff) c
WHERE c.daysdiff > 120;

DBFiddle Demo

Prós:

  • definição única de expressão (mais fácil de manter/sem necessidade de copiar e colar)
  • não há necessidade de envolver toda a consulta com CTE/outerquery
  • possibilidade de se referir em WHERE/GROUP BY/ORDER BY
  • possível melhor desempenho (execução única)
3
Lukasz Szozda