引用WHERE子句中的列别名

时间:2011-12-03 18:57:01

标签: sql sql-server tsql sql-server-2005

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

我得到了

  

“无效的列名称daysdiff”。

Maxlogtm是一个日期时间字段。这是让我疯狂的小东西。

9 个答案:

答案 0 :(得分:156)

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

或者看看Adam对CTE版本的答案。

答案 1 :(得分:68)

如果要在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

答案 2 :(得分:8)

如果您不想在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

答案 3 :(得分:8)

在不重复代码的情况下执行此操作的最有效方法是使用 HAVING 而不是 WHERE < / p>

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

答案 4 :(得分:5)

如何使用子查询(这在Mysql中对我有用)?

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

答案 5 :(得分:4)

HAVING适用于MySQL 根据文件:

  

HAVING 子句已添加到SQL,因为WHERE关键字不能   与聚合函数一起使用。

答案 6 :(得分:3)

您可以引用列别名,但需要使用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

优点:

  • 表达式的单一定义(易于维护/无需复制粘贴)
  • 无需使用CTE /外部查询包装整个查询
  • 可以在WHERE/GROUP BY/ORDER BY中引用
  • 可能会有更好的性能(单次执行)

答案 7 :(得分:1)

对我来说,在WHERE类中使用ALIAS的最简单方法是创建一个子查询,然后从中选择子查询。

示例:

WITH Q1 AS (
    SELECT LENGTH(name) AS name_length,
    id,
    name
    FROM any_table
)

SELECT id, name, name_length form Q1 where name_length > 0

干杯, 凯尔

答案 8 :(得分:0)

在这里看起来与此类似,但是带有CASE WHEN,并且最终使用了这样的位置:WHERE (CASE WHEN COLUMN1=COLUMN2 THEN '1' ELSE '0' END) = 0也许您可以直接在DATEDIFF中使用WHERE。 像这样:

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