引用WHERE子句中的列别名

use*_*016 155 sql t-sql sql-server sql-server-2005

SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120
Run Code Online (Sandbox Code Playgroud)

我明白了

"无效的列名称daysdiff".

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

Jam*_*e F 176

SELECT
   logcount, logUserID, maxlogtm,
   DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE ( DATEDIFF(day, maxlogtm, GETDATE() > 120)
Run Code Online (Sandbox Code Playgroud)

通常,您不能在WHERE子句中引用字段别名.(将其视为整个SELECT包含别名,在WHERE子句之后应用.)

但是,正如其他答案中所提到的,您可以强制SQL SELECTWHERE子句之前处理.这通常用括号来强制执行逻辑操作顺序或使用公用表表达式(CTE):

括号/子选择:

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

或者看看Adam对CTE版本的回答.

  • 这是不可能直接的,因为按时间顺序,WHERE发生在SELECT之前,它始终是执行链中的最后一步.请参阅 - http://stackoverflow.com/questions/356675/using-an-alias-in-a-where-clause (14认同)

Ada*_*ger 71

如果要在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
Run Code Online (Sandbox Code Playgroud)

  • CTE对于子查询来说只是更漂亮的语法,因此性能与此类似.根据我的经验,性能差异并没有让我担心这样的操作,但是在你的环境中测试它应该相当简单,看看你的特定表/查询是否会对此产生负面影响.公式具体在where子句中.我怀疑你不会注意到差异. (5认同)
  • 您是否知道这种公平的交易效率如何?使用CTE是否会有额外的开销? (2认同)

Rom*_*kar 9

如果您不想在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
Run Code Online (Sandbox Code Playgroud)


Pas*_*cal 9

无需重复执行代码的最有效方法是使用HAVING而不是WHERE

SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
HAVING daysdiff > 120
Run Code Online (Sandbox Code Playgroud)

  • 我认为在别名上使用“HAVING”不是标准的(不过它确实适用于 MySQL)。具体来说,我认为它不适用于 SQL Server。 (3认同)
  • SQL Server:`[S0001][207] 列名“daysdiff”无效 (3认同)
  • SQL Server:`[S0001] [8121]列'day'在HAVING子句中无效,因为它不包含在聚合函数或GROUP BY子句中。 (2认同)

She*_*shi 6

怎么样使用子查询(这在Mysql中对我有用)?

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


小智 5

根据文档,HAVING 在 MySQL 中工作:

HAVING子句被添加到SQL,因为关键字无法与合计函数使用的地方。

  • 问题是关于 sql-server 的 (3认同)
  • 尽管问题是关于 SQL Server 的,但这个答案对我们使用 mysql 非常有帮助,我们通过 google 到达这里!谷歌不会索引问题标签,所以感谢您的回答! (3认同)

Luk*_*zda 5

您可以引用列别名,但需要使用以下方式定义它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;
Run Code Online (Sandbox Code Playgroud)

DBFiddle 演示

优点:

  • 表达式的单一定义(更易于维护/无需复制粘贴)
  • 无需使用 CTE/outerquery 包装整个查询
  • 参考的可能性WHERE/GROUP BY/ORDER BY
  • 可能更好的性能(单次执行)

  • @MartinZinovsky 问题被标记为“sql-server”和“t-sql”:) (2认同)