I stumbled upon a strange behavior of MySQL (v.8) when trying to run a nested subquery in the FROM clause. The (relevant part of the) schema of the sample database I am using is as follows:
The following two queries run identically on SQL Server:
SELECT SUM(tot) as total
FROM (
SELECT
SUM(OD.quantityOrdered * OD.priceEach) as tot,
C.customerNumber
FROM customers C
INNER JOIN orders O ON C.customerNumber = O.customerNumber
INNER JOIN orderdetails OD ON O.orderNumber = OD.orderNumber
GROUP BY O.orderNumber, C.customerNumber
) AS CO
GROUP BY CO.customerNumber;
and
SELECT
(
SELECT SUM(tot) as total
FROM
(
SELECT
(
SELECT SUM(OD.quantityOrdered * OD.priceEach)
FROM orderdetails OD
WHERE OD.orderNumber = O.orderNumber
) AS tot
FROM orders O
WHERE O.customerNumber = C.customerNumber
) AS ORD
) AS total
FROM customers AS C;
However, on MySQL, the first one runs fine, while the second one results in an error:
Error Code: 1054. Unknown column 'C.customerNumber' in 'where clause'
I will appreciate any clues about why this is happening. Please note that I am mostly interested not in workarounds or other ways to implement this query, but in understanding the reasons why the nested query fails.
C table alias in not in scope for the suquery
try refactoring the query using a join
eg
select c.customerNumber, t.my_tot
FROM customers AS C
INNER JOIN (
SELECT O.customerNumber, SUM(OD.quantityOrdered * OD.priceEach) my_tot
FROM orderdetails OD
INNER JOIN orders O ON OD.orderNumber = O.orderNumber
GROUP BY O.customerNumber
) t on t.customerNumber = c.customerNumber
or
select t.my_tot
FROM customers AS C
INNER JOIN (
SELECT O.customerNumber, SUM(OD.quantityOrdered * OD.priceEach) my_tot
FROM orderdetails OD
INNER JOIN orders O ON OD.orderNumber = O.orderNumber
GROUP BY O.customerNumber
) t on t.customerNumber = c.customerNumber
you can try like below
SELECT
(
select SUM(tot) as total from
(
SELECT
(
SELECT SUM(OD.quantityOrdered * OD.priceEach)
FROM orderdetails OD
WHERE OD.orderNumber = O.orderNumber
) AS tot,customerNumber
FROM orders O
) as ord
WHERE ord.customerNumber = C.customerNumber
) AS total
FROM customers AS C;
Your customers table not in scope of subquery where you used in where condition WHERE O.customerNumber = C.customerNumber
so i made alias of that and then later level i used same condition where customers table has scope
You have a correlated subquery in the second case. However, the correlation clause is two levels deep .
Many databases will still recognize c
, even when nested multiple levels. However, MySQL (and Oracle and I think MS Access) is a database that limits correlation clauses to one level deep.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.