2010-11-01 56 views
47

我有以下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 

而且我得到这个错误:

#1054 - 未知列 'p.id' 在“on子句'

据我所见,查询看起来是正确的,任何想法可能是错的?

+0

我确定你已经检查过了,但你在表'property'上确实有一个'id'列,它的别名是p? – 2010-11-01 00:51:41

回答

84

不要混合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

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 

相关链接:

  • However, the precedence of the comma operator is less than of INNER JOIN, CROSS JOIN, LEFT JOIN, and so on. If you mix comma joins with the other join types when there is a join condition, an error of the form Unknown column 'col_name' in 'on clause' may occur. Information about dealing with this problem is given later in this section.

    我使用ANSI-92式的连接,即使用JOIN关键字建议总是Why isn't SQL ANSI-92 standard better adopted over ANSI-89?

+0

没有关于JOIN语法的“隐式”或“显式”这样的术语。 – 2010-11-01 00:57:46

+5

优秀的答案。这立即解决了问题,并给了我额外的信息,以帮助我下次。谢谢马克。 – 2010-11-01 01:25:03

0

我碰到了这个错误未知的列,差异是查询是通过HQL里面session.executeQuery(“选择ID,名称,总和(支付),custType从cust group按品牌”),这就是为什么必须手动输入内部连接或连接关键字不是一个选项,因为hql是生成它的一个选项。 它产生的查询sumthing这样的:

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

它说:“未知c.custTypeId”一栏时,我101%肯定它承担该列。

我的类/关系:

Customer { 
Integer custId 
CustomerType custType 
} 

CustomerType{ 
Integer custTypeId 
string code 
} 

问题出在逗号 “从客户,custType” 行。应该用JOIN这个词作为上面的答案。但由于它是HQL并正在生成,所以我不能那样做。我所做的是通过查询进行修改,而不是键入select custType,我键入select custType.id, custType.code

我知道这是基本的,但对于像我这样的第一次定时器来说,这是一场斗争。

7

如前所述,使用通过逗号运算符连接的优先级问题会执行LEFT JOIN,因此在此时不会引用表别名。虽然你可以暗中告诉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 

注意用逗号分隔的表都包含在括号内() 。表别名和列现在可用于其他JOIN。