【问题标题】:MySQL using Inner joins on an alias of a calculated columnMySQL 在计算列的别名上使用内连接
【发布时间】:2012-07-25 23:38:09
【问题描述】:

我有一个这样的查询:

SELECT User.id, 10*10 as distance
FROM USERS
INNER JOIN
(
    SELECT Location.user_id,
    min(10 * 10) as mindistance
    FROM Location
    GROUP BY Location.user_id
 ) L ON Users.id = Location.user_id AND distance = L.mindistance

如果我保持原样,我会不断得到:

Unknown column 'distance' in 'on clause'

但如果我把 User.distance 而不是距离,我得到:

MySQL syntax error near....

我不能在计算字段上以这种方式使用别名吗? 10 * 10 只是一个简单的占位符,因为计算要复杂得多。

【问题讨论】:

标签: mysql sql group-by alias


【解决方案1】:

您正在尝试在ON 子句中使用列别名。 MySQL documentation 对这种情况有这样的说法:

ON 一起使用的conditional_expr 是可以在WHERE 子句中使用的任何形式的条件表达式。

And also:

标准 SQL 不允许在 WHERE 子句中引用列别名。施加此限制是因为在评估 WHERE 子句时,可能尚未确定列值。例如,下面的查询是非法的:

也就是说,您可以使用变量计算ON子句中的表达式,然后使用列列表中的值,如下所示:

SELECT User.id, @dist as distance
FROM USERS
INNER JOIN
(
    SELECT Location.user_id,
    min(10 * 10) as mindistance
    FROM Location
    GROUP BY Location.user_id
 ) L ON Users.id = Location.user_id AND (@dist := 10*10) = L.mindistance

【讨论】:

  • 作者的SQL中没有WHERE子句。
  • 固定@JohnFactorial
【解决方案2】:

为避免在查询中进行三次计算,您可以将外部计算包装在 FROM 子选择中,这样您就可以访问别名字段名称(在原始查询中无法访问该名称) ):

SELECT a.*
FROM
(
    SELECT id, 10*10 AS distance
    FROM USERS
) a
INNER JOIN
(
    SELECT user_id,
    MIN(10 * 10) AS mindistance
    FROM Location
    GROUP BY user_id
) L ON a.id = L.user_id AND a.distance = L.mindistance

这里只计算了两次而不是三次。

【讨论】:

    【解决方案3】:

    您不能在查询 where 子句中使用派生值 - where 用于限制记录和使用哪些索引 - 派生值不能被优化器使用,因此您需要过滤最终结果。

    不太确定你在做什么,但可以试试:

    SELECT User.id, 10*10 as distance 
    FROM USERS 
    INNER JOIN 
    ( 
        SELECT Location.user_id, 
        min(10 * 10) as mindistance 
        FROM Location 
        GROUP BY Location.user_id 
    ) L ON User.id = Location.user
    HAVING USERS.distance = L.mindistance
    

    【讨论】:

      【解决方案4】:
      SELECT User.id, 10*10 as distance 
      FROM USERS 
      INNER JOIN 
      ( 
          SELECT Location.user_id, 
          min(10 * 10) as mindistance 
          FROM Location 
          GROUP BY Location.user_id 
       ) L ON User.id = Location.user_id AND L.mindistance =10*10
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-15
        • 1970-01-01
        • 2011-04-18
        • 1970-01-01
        • 2011-07-03
        • 2019-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多