【问题标题】:MySQL unknown column in ON clauseON子句中的MySQL未知列
【发布时间】:2011-05-03 05:35:31
【问题描述】:

我有以下 MySQL 查询:

SELECT p.*,
    IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
    pm.MediaID,
    date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
    astext(pg.Geometry) AS Geometry
FROM property p, propertygeometry pg
    JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
    LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
    LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
WHERE p.paused = 0
    AND p.PropertyGeometryID = pg.id
GROUP BY p.id

我收到了这个错误:

#1054 - 'on clause' 中的未知列 'p.id'

据我所见,查询看起来是正确的,知道可能有什么问题吗?

【问题讨论】:

  • 我确定您已经检查过了,但是您在表 property 上确实有一列 id 别名为 p?

标签: sql mysql mysql-error-1054


【解决方案1】:

如前所述,通过逗号运算符使用连接存在优先级问题,其中将执行 LEFT JOIN,因此此时不存在对表别名的引用。虽然您可以通过该语句隐式告诉 MySQL 使用 JOIN,但您也可以告诉 MySQL 先评估逗号连接的表,然后执行左连接:

SELECT p.*,
IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
pm.MediaID,
date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
astext(pg.Geometry) AS Geometry
FROM (property p, propertygeometry pg)
JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
WHERE p.paused = 0
AND p.PropertyGeometryID = pg.id
GROUP BY p.id

请注意,逗号分隔的表格包含在括号 () 中。表别名和列现在将可供您的其他 JOIN 使用。

【讨论】:

    【解决方案2】:

    我碰到了这个错误未知列,不同之处在于查询是通过 session.executeQuery("select id, name, sum(paid), custType from cust group by brand") 中的 HQL 构建的,这就是为什么必须手动输入inner join 或 join 关键字不是一个选项,因为 hql 是生成它的那个。 它会产生这样的查询总和:

    select cust_id, name, sum(paid), c.custTypeId
    from customer c, custType ct
    on c.custTypeId  = ct.custTypeId 
    

    当我 101% 确定它包含该列时,它会显示“未知 c.custTypeId”列。

    我的班级/关系:

    Customer {
    Integer custId
    CustomerType custType
    }
    
    CustomerType{
     Integer custTypeId
    string code
    }
    

    问题在于“from customer, custType”行中的逗号。它应该使用 JOIN 作为上述答案。但由于它是 HQL 并且正在生成,所以我不能这样做。我所做的是通过查询修改,而不是输入 select custType,而是输入 select custType.id, custType.code

    我知道这是基本的,但对于像我这样的初学者来说,这是一场斗争。

    【讨论】:

      【解决方案3】:

      不要混合使用 ANSI-89 样式和 ANSI-92 样式连接。它们具有不同的优先级,这可能会导致令人困惑的错误,这就是这里发生的情况。您的查询被解释如下:

      FROM property p, (
          propertygeometry pg
          JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
          ...
      )
      

      在上面,首先评估使用 JOIN 关键字的连接,然后再考虑逗号样式的连接。此时表 p 尚未声明。

      来自MySQL manual

      但是,逗号运算符的优先级低于 INNER JOIN、CROSS JOIN、LEFT JOIN 等。如果在存在连接条件时将逗号连接与其他连接类型混合使用,则可能会出现 Unknown column 'col_name' in 'on Clause' 形式的错误。本节稍后将提供有关处理此问题的信息。

      我建议始终使用 ANSI-92 样式的连接,即使用 JOIN 关键字:

      SELECT p.*,
          IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
          pm.MediaID,
          date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
          astext(pg.Geometry) AS Geometry
      FROM property p
          JOIN propertygeometry pg ON p.PropertyGeometryID = pg.id
          JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
          LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
          LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
      WHERE p.paused = 0
      GROUP BY p.id
      

      相关:

      【讨论】:

      • 没有关于 JOIN 语法的“隐式”或“显式”等术语。
      猜你喜欢
      • 1970-01-01
      • 2014-03-13
      • 1970-01-01
      • 2012-05-16
      • 2018-05-12
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多