你能在SQL的WHERE语句中使用“即时”列名吗?

3

我对SQL有点生疏。

我原以为可以这样做:

SELECT *, DATEADD(d, 1 ,dStartDateTime) dCloseDate
FROM EventItem 
WHERE dCloseDate > '1990-01-01 07:00:00.000'

但是当我这样做时,会出现错误:
Invalid column name 'dCloseDate'.

有人知道如何解决这个问题吗?我只是想这样做可以使我的代码更易读/易维护。

如果有任何建议不应该这样做也将不胜感激 :)


根据您使用的SQL服务器,我更喜欢使用CTE来完成这种操作。 - Andrew
3个回答

5

在SQL的WHERE子句中,你不能使用“即时”列名。(在ORDER BY子句中可以。)你必须将其作为子查询或重复表达式。

SELECT * FROM (
SELECT *, DATEADD(d, 1 ,dStartDateTime) dCloseDate
FROM EventItem
) SUBQ
WHERE dCloseDate > '1990-01-01 07:00:00.000'

-or-

SELECT *, DATEADD(d, 1 ,dStartDateTime) dCloseDate
FROM EventItem 
WHERE DATEADD(d, 1 ,dStartDateTime) > '1990-01-01 07:00:00.000'

为什么不应该这样做?

话虽如此,但您正在对列 dStartDateTime 执行需要进行表扫描的函数。请始终在另一侧执行函数,以便可以针对 dStartDateTime(日期时间列)上的索引测试找到的值。

SELECT *, DATEADD(d, 1 ,dStartDateTime) dCloseDate
FROM EventItem 
WHERE dStartDateTime > DATEADD(d, -1 ,'1990-01-01 07:00:00.000')

非常出色和快速的回答!谢谢。不过,当你说我应该在“另一边”执行我的函数时,你是什么意思?你是指在WHERE子句中执行,而不是SELECT中吗? - Ev.
@Ev - 我的意思是,与其在日期上执行函数以与值进行比较,不如在值(“另一侧”)上执行函数,这最终会得到...只是另一个值。现在,SQL Server可以使用索引快速定位该(范围)值。 - RichardTheKiwi
是的,关于在WHERE子句(以及ON子句)中不对列应用函数的观点尤其有用,即使只是作为提醒。 - Andriy M

1

很遗憾,您无法使用AS子句中给出的名称。相反,您必须在WHERE子句中重复表达式:

SELECT *, DATEADD(d, 1 ,dStartDateTime) AS dCloseDate
FROM EventItem 
WHERE DATEADD(d, 1 ,dStartDateTime) > '1990-01-01 07:00:00.000'

这并不会提高代码的可读性或可维护性,但这是唯一的方法。


0

抱歉,您不能在where子句(或group bys或order bys)中引用列别名(例如dCloseDate)。如果可以的话,那就太好了,但是MS SQL不支持该功能。


1
您可以在ORDER BY中使用它们。事实上,这是推荐的方法,而不是按列位置排序。 - RichardTheKiwi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接