带有计算值的SQL WHERE子句

时间:2015-09-22 04:06:52

标签: mysql sql

看来我不能在WHERE子句中使用计算值?

SELECT id, TIMESTAMPDIFF(YEAR,dateOfBirth,CURDATE()) AS age 
FROM user
WHERE age >= 20

我得到ERROR 1054 (42S22): Unknown column 'age' in 'where clause'。一个可能的解决方法是使用子查询但它过于复杂的东西?

4 个答案:

答案 0 :(得分:6)

可以 WHERE子句中使用计算值,但不使用其别名。您必须再次输入整个表达式

WHERE TIMESTAMPDIFF(YEAR,dateOfBirth,CURDATE()) >=20
  

可以在查询选择列表中使用别名为列提供不同的名称。您可以使用GROUP BY,ORDER BY或HAVING子句中的别名来引用该列:

     

标准SQL不允许在WHERE子句中引用列别名。强制执行此限制是因为在评估WHERE子句时,可能尚未确定列值。

<强> Reference

答案 1 :(得分:3)

是的,但mySQL的行为与你想的不一样

SELECT id, TIMESTAMPDIFF(YEAR,dateOfBirth,CURDATE()) AS age 
FROM user
WHERE TIMESTAMPDIFF(YEAR,dateOfBirth,CURDATE()) >= 20

mySQL WHERE CLAUSE只查看列而不是别名。

答案 2 :(得分:0)

正如其他人所指出的,您不能在WHERE子句中使用列别名。 HAVING子句也是如此。但是您可以在ORDER BY子句中使用列别名(只要它不是要计算的表达式)。因此混乱。

答案 3 :(得分:0)

我更喜欢以下面的方式执行上面的sql 请注意,我更改了查询并在T-SQL中重新编码 但我相信SQL引擎的逻辑将执行相同的

declare @curdate datetime = getdate()
declare @date20 datetime = dateadd(yy,-20,@curdate)

SELECT id, DATEDIFF(YEAR,dateOfBirth,@curdate) AS age 
FROM [user]
WHERE dateOfBirth <= @date20

在WHERE子句中,我更喜欢使用其值之前计算的静态变量。这种类型的WHERE标准允许在我们的例子中使用INDEX on dateOfBirth列。这提高了查询的性能

否则,至少在SQL Server中有一个WHERE子句,如下所示

WHERE DATEDIFF(YEAR,dateOfBirth,@curdate) >= 20

将无法在dateOfBirth列上使用INDEX,因此查询性能