mysql ...in where clause is ambiguous
The error you get tells you that the column CategoryID
in your WHERE
clause is ambiguous, that means that the system has a problem to identify the appropriate column because there are multiple CategoryID
columns.
In order to fix this problem, use the alias to specify which column you want to use for your WHERE
clause:
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
I also changed a bit the query to get the same result but instead of using a combination of LEFT JOIN
+ IN
clause + sub query, i used INNER JOIN
clauses.
With this query you only need to define your desired CategoryID
once and it will automatically get every child categories.
I'm not sure that your query runs correctly because you're using the COUNT
function without grouping the results by CategoryID
...
Hope this will help you.
The "ambiguous column" error means that there's a reference to a column identifier, and MySQL has two (or more) possible columns that match the specification.
In this specific case, it's the reference to CategoryID
column in the WHERE
clause.
It's "ambiguous" whether CategoryID
is meant to refer to the CategoryID
column from cat
, or refer to the CategoryID
column from p
.
The fix is to qualify the column reference with the table alias to remove the ambiguity. That is, in place of CategoryID
, specify either cat.CategoryID
or p.CategoryID
.
Some additional notes:
It's very odd to have an IN (subquery)
predicate in the ON
clause. If CategoryID
is not guaranteed to be unique in the Category
table, this query would likely generate more rows than would be expected.
The normal pattern for a query like this would be something akin to:
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
Normally, the join predicates in the ON
clause reference columns in two (or more) tables in the FROM clause. (That's not a SQL requirement. That's just the usual pattern.)
The predicate in the ON
clause of the query above specifies that the value of the CategoryID
column from the cat
(Category) table match the value in the CategoryID
column from the p
(Product) table.
Also, best practice is to qualify all columns referenced in a query with the name of the table, or a table alias, even if the column names are not ambiguous. For example, the Name
column in the ORDER BY
clause.
One big benefit of this is that if (at some time in the future) a column named Name
is added to the Products
table, the query with an unqualified reference to Name
would (then) begin to throw an "ambiguous column" error for the that reference. So, qualifying all column names avoids a working query "breaking" when new columns are added to existing tables.
Another big benefit is that to the reader of the statement. MySQL can very quickly look in the dictionary, to find which table Name
is in. But readers of the SQL statement (like myself) who do not "know" which table contains the column named Name
, would also need to look at the table definitions to find out. If the name were qualified, we would already "know" which table that column was from.