Ссылаясь на псевдоним столбца в предложении WHERE - PullRequest
140 голосов
/ 03 декабря 2011
SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120

Я получаю

"неверное имя столбца daysdiff".

Maxlogtm - поле даты и времени.Это мелочи, которые сводят меня с ума.

Ответы [ 7 ]

160 голосов
/ 03 декабря 2011
SELECT
   logcount, logUserID, maxlogtm,
   DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE ( DATEDIFF(day, maxlogtm, GETDATE() > 120)

Обычно вы не можете ссылаться на псевдонимы полей в предложении WHERE.(Представьте себе, что весь SELECT, включая псевдонимы, применяется после предложения WHERE.)

Но, как упоминалось в других ответах, вы можете заставить SQL обрабатывать SELECT для обработки доWHERE предложение.Обычно это делается с помощью скобок для принудительного логического порядка операций или с помощью общего табличного выражения (CTE):

Скобки / Подвыбрать:

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

Или см. Ответ Адама для версии CTE:то же самое.

69 голосов
/ 03 декабря 2011

Если вы хотите использовать псевдоним в предложении WHERE, вам нужно заключить его в суб-выборку или 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
9 голосов
/ 08 августа 2016

Самый эффективный способ сделать это без повторения кода - это использовать HAVING вместо WHERE

SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
HAVING daysdiff > 120
8 голосов
/ 10 октября 2014

Если вы не хотите перечислять все свои столбцы в CTE, другой способ сделать это - использовать 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
5 голосов
/ 31 марта 2015

Как насчет использования подзапроса (у меня это работало в Mysql)?

SELECT * from (SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary) as 'your_alias'
WHERE daysdiff > 120
4 голосов
/ 18 марта 2017

HAVING работает в MySQL в соответствии с документацией:

В SQL добавлено предложение HAVING , поскольку ключевое слово WHERE не может использоваться с агрегатными функциями.

3 голосов
/ 26 августа 2018

Вы можете ссылаться на псевдоним столбца, но вам нужно определить его, используя 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

Плюсы:

  • единичное определение выражения (легче поддерживать / не нужно копировать-вставлять)
  • нет необходимости переносить весь запрос с помощью CTE / externalquery
  • возможность ссылаться на WHERE/GROUP BY/ORDER BY
  • возможно лучшая производительность (одиночное исполнение)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...