MYSQL 在 WHERE 子句中使用别名

mrt*_*nyb 2 mysql

我读过你不能在 WHERE 子句中使用 ALIAS,但我仍然没有一个好的替代解决方案来实现我在下面尝试做的事情。我可以用我的 DISTANCE 计算做什么,以便它在 WHERE 子句中可用?

SELECT n.nid AS nid, location.name AS location_name, (6371.0 * ACOS(SIN((location.latitude * RADIANS(1))) * SIN((28.755925 * RADIANS(1))) + COS((location.latitude * RADIANS(1))) * COS((28.755925 * RADIANS(1))) * COS((location.longitude * RADIANS(1)) - (-81.346395 * RADIANS(1))))) AS distance
            FROM 
            node n
            LEFT JOIN location_instance ON n.vid = location_instance.vid
            LEFT JOIN location ON location_instance.lid = location.lid
            WHERE (( (n.status = '1') AND (n.type IN  ('locations')) AND (distance <= 100) ))
            ORDER BY distance
            LIMIT 10
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 5

MySQL 扩展了HAVING子句的使用,可用于此目的。如果查询不是聚合查询,则HAVING仍会进行过滤——但它允许使用别名。

所以,你可以写:

SELECT n.nid AS nid, l.name AS l, (6371.0 * ACOS(SIN((l.latitude * RADIANS(1))) * SIN((28.755925 * RADIANS(1))) + COS((l.latitude * RADIANS(1))) * COS((28.755925 * RADIANS(1))) * COS((l.longitude * RADIANS(1)) - (-81.346395 * RADIANS(1))))) AS distance
FROM node n LEFT JOIn
     location_instance li
     ON n.vid = li.vid LEFT JOIN
     location l
     ON li.lid = l.lid
WHERE n.status = 1 AND n.type IN ('locations') 
HAVING distance <= 100
ORDER BY distance
LIMIT 10;
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 如果status是一个数字,这似乎很可能,那么您应该与一个数字进行比较,而不是一个字符串。
  • 表别名使查询更易于编写和阅读。
  • 虽然status并且type可以进入HAVING子句,但我怀疑它们在WHERE(我怀疑这HAVING可能会影响优化选择)中更好。
  • 您可以使用子查询,但这会将所有数据存储在表中。