on子句中的MySQL未知列

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (41)

我有以下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 cluses”中的“p.id”列

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

提问于
用户回答回答于

不要混合ANSI-89风格和ANSI-92风格的联接.。它们有不同的优先级,可能导致混淆错误,这就是这里发生的情况。对你的查询的解释如下:

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

在上面,使用JOIN关键字的联接在考虑逗号式连接之前首先进行评估。在那一点上,桌子p还没有宣布。

MySQL手册:

然而,逗号运算符的优先级小于内部联接、交叉连接、左联接等。如果在有联接条件时将逗号联接与其他联接类型混合,则窗体的错误。未知柱_把‘in’in‘on cluses’命名为可能会发生。有关处理此问题的信息将在本节后面给出。

我建议使用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
用户回答回答于

如前所述,在通过逗号运算符使用联接时存在一个优先级问题,其中将执行左联接,因此对表别名的引用在那时不存在。虽然可以通过该语句隐式告诉MySQL使用一个联接,但也可以告诉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

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

扫码关注云+社区