在MySQL SELECT查询中,我可以在WHERE规范中使用我的“AS列”吗?

时间:2010-12-28 19:51:11

标签: mysql

在我的数据库中,我计算节点之间的距离:

SELECT DISTINCT
       dest.name,
       AsText(orig.location),
       AsText(dest.location),
       round((glength(linestringfromwkb(linestring((orig.location), (dest.location)))))) as distance
FROM nodes orig,
     nodes dest
WHERE orig.name='GERP'

我想添加

and distance < dest.visibility

最后,但我被告知距离是一个未知的列。

非常感谢任何见解。

5 个答案:

答案 0 :(得分:2)

使用子查询,然后您只需要输入一次公式(如果您需要更改它,则只需更改一次)。

SELECT
       dest.name,
       dest.visibility,
       AsText(orig.location),
       AsText(dest.location),
       distance
FROM (
SELECT DISTINCT
       dest.name,
       dest.visibility,
       AsText(orig.location),
       AsText(dest.location),
       round((glength(linestringfromwkb(linestring((orig.location), (dest.location)))))) as distance
FROM nodes orig,
     nodes dest
WHERE orig.name='GERP'
) AS nodeDistances
WHERE nodeDistainces.distance < visibility

答案 1 :(得分:1)

不,但你可以添加

and dest.visibility > round((glength(linestringfromwkb(linestring((orig.location), (dest.location))))))

mysql应该足够智能,只能计算一次表达式。

答案 2 :(得分:1)

HAVING是你的朋友。

  

可以为select_expr指定别名   使用AS alias_name。使用别名   作为表达式的列名和   可以在GROUP BY,ORDER BY或。中使用   有条款。

     

同时适应标准SQL和   特定于MySQL的行为   能够在SELECT中引用列   列表,MySQL 5.0.2及以上允许HAVING   引用SELECT中的列   list,GROUP BY子句中的列,   外子查询中的列,以及   聚合函数。

请注意,HAVING无法优化,并且会变慢。不过,您的查询不是新问题......

答案 3 :(得分:0)

使用:

SELECT DISTINCT
       dest.name,
       AsText(orig.location),
       AsText(dest.location),
       round((glength(linestringfromwkb(linestring((orig.location), (dest.location)))))) as distance
  FROM nodes orig,
       nodes dest
 WHERE orig.name = 'GERP'
   AND round((glength(linestringfromwkb(linestring((orig.location), (dest.location)))))) < dest.visibility

SQL不允许在WHERE子句中访问列别名 - 最早的MySQL支持是GROUP BY子句。

此外,您的查询缺少加入两个表实例的条件 - 导致产生笛卡尔积。

答案 4 :(得分:0)

您不能在where子句中使用结果集计算列名。

你需要(遗憾地)重复使用你用来计算它的整个表达式

and round((glength(linestringfromwkb(linestring((orig.location), (dest.location))))))
    < dest.visibility

有两种解决方法:

  1. 如果您在SQL之外创建查询文本(例如,从Perl,PHP等...),您可以在查询之前将表达式存储在字符串中并重新使用字符串:

    $long_expr = "round((glength(linestringfromwkb(linestring((orig.location), (dest.location))))))";
    $sql = qq[SELECT DISTINCT
    

    dest.name,    AsText(orig.location)    AsText(dest.location)    $ long_expr作为距离    ...    和$ long_expr&lt; dest.visibility

  2. 将原始查询(没有最后一个AND)存储在临时表中(但在选择中包含in visibility列),然后执行以下操作

    SELECT * from #temp_table
    WHERE distance < visibility
    
  3. 与#2相同,但不是临时表,请执行子查询。