Why is this query not working?
Select temp.CompanyName from
(
SELECT c.CompanyName, o.OrderID,
YEAR(o.OrderDate) As YEAR,
Sum(od.UnitPrice * od.Quantity) from Orders o
INNER JOIN [Order Details] od
ON o.OrderID = od.OrderID
INNER JOIN Customers c
On c.CustomerID = o.CustomerID
GROUP BY o.OrderId,c.CompanyName, YEAR(o.OrderDate)
) As temp;
It uses Northwind database. If I run it without creating a temporary view i.e if I run the query just contained within round brackets it runs just fine.
at the first look i'd say because your Sum() doesn't have a column alias
try this :
Select CompanyName from
(
SELECT c.CompanyName, o.OrderID,
YEAR(o.OrderDate) As YEAR,
Sum(od.UnitPrice * od.Quantity) as price from Orders o
INNER JOIN [Order Details] od
ON o.OrderID = od.OrderID
INNER JOIN Customers c
On c.CustomerID = o.CustomerID
GROUP BY o.OrderId,c.CompanyName, YEAR(o.OrderDate)
) temp
Related
I am trying to determine the customers spending behavior by writing a query to select the top 10 highest spenders.
I have the following query and it works fine:
SELECT c.CustomerID
, SUM(Quantity * UnitPrice) Total_Spent
FROM Orders o
JOIN OrderDetails d
ON d.OrderID = o.OrderID
JOIN Customers c
ON c.CustomerID = o.CustomerID
GROUP
BY c.CustomerID
ORDER
BY Total_Spent
limit 10;
However, I want to create a subquery instead of having this complicated one. I have tried the following but it doesn't work:
SELECT Customers.CustomerID
FROM Customers
JOIN (
SELECT SUM(Quantity *UnitPrice) as Total_Spent
FROM Orders
JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID) Orders
ON Orders.CustomerID = Customers.CustomerID
GROUP BY Customers.CustomerID
ORDER BY Total_Spent
LIMIT 10;
I don't know what the problem is. (I am kinda new in SQL)
You can simplify your query because you don't need the customers table. That and table aliases should make your query simpler:
SELECT o.CustomerID, SUM(od.Quantity * od.UnitPrice) as Total_Spent
FROM Orders o JOIN
OrderDetails od
ON o.OrderID = od.OrderID
GROUP BY o.CustomerID
ORDER BY Total_Spent DESC
LIMIT 10;
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.
I have created two queries that both return the required results independent of each other. I am trying to join them to have the returned values be customerName, Amount Ordered, and Amount Paid.
Currently, this query works but only returns the customerName. How can it get the query to return the other two columns?
SELECT c1.customerName
FROM
(SELECT cc.customerName, ROUND(SUM(od.priceEach * od.quantityOrdered), 2) as '$ Amount Ordered'
FROM customers cc
INNER JOIN orders o ON o.customerNumber = cc.customerNumber
INNER JOIN orderdetails od ON od.orderNumber = o.orderNumber
GROUP BY cc.customerName
) c1
INNER JOIN
(SELECT c.customerName, ROUND(SUM(p.amount), 2) as 'Total $ Amount Paid'
FROM customers c
INNER JOIN payments p ON p.customerNumber = c.customerNumber
GROUP BY c.customerName
) c2
WHERE c1.customerName = c2.customerName
GROUP BY c1.customerName
ORDER BY c1.customerName;
this should select the others column
SELECT c1.customerName, c1.Amount_Ordered as '$ Amount Ordered', c2.Total_Amount_Paid as 'Total $ Amount Paid'
FROM
(SELECT cc.customerName, ROUND(SUM(od.priceEach * od.quantityOrdered), 2) as Amount_Ordered
FROM customers cc
INNER JOIN orders o ON o.customerNumber = cc.customerNumber
INNER JOIN orderdetails od ON od.orderNumber = o.orderNumber
GROUP BY cc.customerName
) c1
INNER JOIN
(SELECT c.customerName, ROUND(SUM(p.amount), 2) as Total_Amount_Paid
FROM customers c
INNER JOIN payments p ON p.customerNumber = c.customerNumber
GROUP BY c.customerName
) c2
WHERE c1.customerName = c2.customerName
GROUP BY c1.customerName
ORDER BY c1.customerName;
simply add them to the select section:
SELECT c1.customerName, C1.amountOrdered, C2.amountPaid FROM ...
And one more word of advice - DONT use whitespace or special signs like $ in your column names, it is bad practice. I think it's a mistake that mySql even allows it
I'm trying to get the sum of each customer's orders separately, but I'm actually getting the sum of all the orders. What am I doing wrong here?
SELECT c.customerNumber, sum( r.quantityOrdered * r.priceEach ) AS sum
FROM customers c, orders o, orderdetails r
WHERE c.customerNumber = o.customerNumber
AND o.orderNumber = r.orderNUmber
GROUP BY c.customerNumber
HAVING COUNT( o.orderNumber ) <=3
First, you should use JOIN as it is the standardised way of writing the syntax. Makes it easier to read.
SELECT c.customerNumber, sum( r.quantityOrdered * r.priceEach ) AS sum
FROM customers c
LEFT JOIN orders o ON c.customerNumber = o.customerNumber
LEFT JOIN orderdetails r ON o.orderNumber = r.orderNUmber
GROUP BY c.customerNumber
HAVING COUNT( o.orderNumber ) <=3
When you use LEFT JOIN, this will give the results of the table customers, even if they dont have any recods in the orders and orderdetails.
Give it a try!
Your query looks ok to me other than the HAVING clause. I don't know what you are really trying to achieve with HAVING COUNT( o.orderNumber ) <=3. Do you really want customers with order of 3 or less? Have you tried using :
SELECT c.customerNumber, sum(r.quantityOrdered * r.priceEach) AS sum
FROM customers c
INNER JOIN orders o ON c.customerNumber = o.customerNumber
INNER JOIN orderdetails r ON o.orderNumber = r.orderNUmber
GROUP BY c.customerNumber
In my query below, i am trying to join one result set to another using the customerNumber identifier. I want to find each customer's amount ordered and the amount paid. The sql does not execute with no help from Navicat Client
SELECT DISTINCT tabl1.customerNumber,
tabl1.amountOrdered, tabl2.amountPaid
FROM
(
SELECT Distinct c.customerNumber, o.orderNumber,
SUM(od.quantityOrdered * od.priceEach) amountOrdered
FROM ClassicModels.Customers c
INNER JOIN ClassicModels.Orders o
ON c.customerNumber = o.customerNumber
INNER JOIN ClassicModels.OrderDetails od
ON o.orderNumber = od.orderNumber
GROUP BY od.orderNumber
ORDER BY c.customerNumber
) tabl1
INNER JOIN
(
SELECT DISTINCT c.customerNumber, p.amount amountPaid
FROM ClassicModels.Customers c
INNER JOIN ClassicModels.Payments p
ON c.customerNumber = p.customerNumber
) tabl2 ON tabl1.customerNumber = tabl2.customerNumber
If you want to select each customer's amount ordered and amount paid, this much simpler query should work:
SELECT o.customerNumber as customerNumber,
SUM(od.quantityOrdered * od.priceEach) as amountOrdered,
SUM(p.amount) as amountPaid
FROM ClassicModels.Orders o
INNER JOIN ClassicModels.OrderDetails od
ON o.OrderNumber = od.OrderNumber
LEFT JOIN ClassicModels.Payments p
ON p.customerNumber = o.customerNumber
GROUP BY o.customerNumber