mysql ...在where子句中是不明确的

时间:2014-09-05 04:48:49

标签: mysql sql

SELECT
                cat.CategoryID as CategoryID,
                count(p.ProductID) as CountProducts
            FROM 
                Category as cat
                LEFT JOIN Products as p on p.CategoryID IN 
                       (SELECT CategoryID FROM Category as cd 
                           WHERE cd.ParrentCategoryID = '876')
            WHERE 
                CategoryID = '876'
            ORDER by Name

我们收到错误 - "列' CategoryID'在where子句中含糊不清"。

请告诉我,这是对的?

3 个答案:

答案 0 :(得分:2)

您收到的错误告诉您CategoryID子句中的列WHERE不明确,这意味着系统在识别相应列时遇到问题,因为有多个CategoryID列。

要解决此问题,请使用别名指定要用于WHERE子句的列:

SELECT cat2.CategoryID AS CategoryID
    ,cat2.Name AS CategoryName
    ,COUNT(p.ProductID) AS CountProducts
FROM Category AS cat
INNER JOIN Category AS cat2 ON cat2.ParrentCategoryID = cat.CategoryID
INNER JOIN Products AS p ON p.CategoryID = cat2.CategoryID
WHERE cat.CategoryID = '876'
GROUP BY cat2.CategoryID, cat2.Name
ORDER BY cat2.Name

我还改变了一些查询以获得相同的结果,但我没有使用LEFT JOIN + IN子句+子查询的组合,而是使用了INNER JOIN子句。 使用此查询,您只需定义一次所需的CategoryID,它就会自动获取每个子类别。

我不确定您的查询是否正确运行,因为您使用的是COUNT函数而未按CategoryID对结果进行分组...

希望这会对你有所帮助。

答案 1 :(得分:1)

尝试WHERE cat.CategoryID = '876'

答案 2 :(得分:0)

“模糊列”错误表示存在对列标识符的引用,并且MySQL具有与规范匹配的两个(或更多)可能列。在此特定情况下,CategoryID子句中对WHERE列的引用。这是“含糊不清”的,是指CategoryID中的cat列,还是p中的CategoryID列。

“修复”是使用表别名cat.CategoryIDp.CategoryID来限定该列引用。


一些补充说明:

IN (subquery)子句中有一个ON谓词很奇怪。如果CategoryID表中Category不能保证唯一,则此查询可能会生成比预期更多的行。

像这样的查询的正常模式类似于:

SELECT cat.CategoryID     AS CategoryID
     , COUNT(p.ProductID) AS CountProducts
  FROM Category cat
  LEFT 
  JOIN Products p
    ON p.CategoryID = cat.CategoryID 
 WHERE cat.ParrentCategoryID = '876'
 ORDER BY cat.Name

通常,连接在FROM子句中的两个(或更多)表中的ON子句引用列中进行谓词。 (这不是SQL要求。这只是通常的模式。)

上述查询的ON子句中的谓词指定CategoryID(类别)表cat列的值与值相匹配在CategoryID(产品)表的p列中。

此外,最佳做法是使用表名或表别名限定查询中引用的所有列,即使列名不明确。例如,Name子句中的ORDER BY列。

这样做的一大好处是,如果(在将来的某个时间)将一个名为Name的列添加到Products表中,则该查询具有对Name的非限定引用将(然后)开始为该引用抛出“模糊列”错误。因此,限定所有列名称可以避免在将新列添加到现有表时“中断”工作查询。

另一个很大的好处是对于声明的读者。 MySQL可以非常快速查看字典,找到哪个表Name。但是,如果不“知道”哪个表包含名为Name的列,那么SQL语句的读者(比如我自己)会还需要查看表定义才能找到答案。如果名称是合格的,我们就已经“知道”该列来自哪个表。