Rows with Revenue =0, how do I show the 0? - mysql

The following code shows all our customers that have made purchases since our database was created and how much money they have spent. There are a couple customers that have not made purchases since we implemented the new database but they are not appearing when I run this code. I have looked around this site for similar examples but the solutions are too complex for me.
There is also a customers table that shows the results for all of our 'n' customers, that table connects to the orders table through customerID. Not sure if that will help.
select t3.CustomerID, sum(Revenue) as Revenue
from
(
select orderid, sum(UnitPrice*quantity) as Revenue from [Order Details]
group by OrderID
)t1
inner join
(
select customerid,orderid from orders
)t3
on t1.orderid=t3.orderid
group by t3.CustomerID

I think you just want this rather simpler query:
select c.CustomerID, sum(od.UnitPrice * od.quantity) as Revenue
from customers c left outer join
orders o
on o.CustomerId = c.CustomerId left outer join
`Order Details` od
on od.OrderId = o.OrderId
group by c.CustomerID;

Related

MySQL not returning values from NOT IN function

I currently am trying to write a query that shows customers with at least 5 orders and customer with no orders. Orders are tracked in their own table and in order to find customers with 0 orders we have to find the customers NOT IN orders. Below is my query I'm trying to use and it returns the same customer 5 times for zero orders.
with t1 as
(select o.customerNumber, c.customerName, count(o.orderNumber) as FiveOrders
from orders o join customers c on (o.customerNumber = c.customerNumber)
group by o.customerNumber having count(o.orderNumber) = 5),
t2 as
(select distinct o.customerNumber, c.customerName, count(o.orderNumber) as NoOrders
from orders o join customers c on (o.customerNumber = c.customerNumber)
group by c.customerNumber not in(select customerNumber from orders))
select distinct t1.customerNumber as FiveOrderNumber, t1.customerName as FiveOrderName,
t2.customerNumber as NoOrderNumber, t2.customerName as NoOrderName
from t1 join t2
order by NoOrderName;
Any and all help is appreciated thanks!
If the errors were only in the second table to, I think it is after using
having with condition NOT IN without any logical comparison, I think you can get wanted results easily like:
select distinct customerNumber, customerName, "0" as NoOrders
from customers
where customerNumber not in (Select customerNumber from orders)
If the group by is important, you can use it like in your code.
Zero or five could be counted together with LEFT JOIN
select c.customerNumber, max(c.customerName) customerName, count(o.orderNumber) as FiveOrdersOrZero
from customers c
left join orders o on o.customerNumber = c.customerNumber
group by c.customerNumber
having count(o.orderNumber) in ( 0, 5 )
order by FiveOrdersOrZero

Sub queries, Aliases and Stored Values- MySQL

I am given a problem as following:
Create a SQL statement that shows all shipped orders with a total of more than $14,000. The results must contain the customer's first_name, last_name, order_id, order shipped_date, number of items and total amount. Make sure any discount is taken into account when calculating the total amount.
Tables to draw from are:
Order Items: quantity, list_price, discount, order_id
Order: order_id, shipped_date, order_status, customer_id
Customers: first_name, last_name, customer_id.
I'm pretty new to SQL and sub-queries so I tried to build it from inside out and it kept giving me rows returned...until the last join ("sub2"). My code is below (inelegant, but I do need to figure out the problem before worrying about that).
select c.first_name, c.last_name, sub2.order_id, sub2.shipped_date, sub2.quantity, sub2.total_amount from customers AS c
INNER JOIN(
select o.order_id, o.shipped_date, o.order_status, o.customer_id, sub1.total_price FROM orders as o
INNER JOIN (
SELECT oi.order_id, SUM((oi.list_price * oi.quantity) - ((oi.list_price * oi.quantity) * (oi.discount))) AS total_price
FROM order_items AS oi
group by oi.order_id
) AS sub1
ON o.order_id = sub1.order_id
WHERE
sub1.total_price > 14000
AND
o.order_status = 4
) AS sub2
ON c.customer_id = sub2.customer_id
;
The error I'm getting is "Unknown column 'sub2.quantity' in 'field list'"
I imagine Mysql does not like this double nesting, so how can I go about solving this?
There's no problem with nested queries, your problem is that the names on your nested statements don't correlate with the ones used outside as the alias.
eg: ... INNER JOIN(select o.order_id, o.shipped_date, o.order_status, o.customer_id, sub1.total_price FROM ...
doesn't has a quantity casted, so when it's rows are called outside as sub2 there is an Unknown column 'sub2.quantity' in field list, it will fail also with sub2.total_amount for the same reason.
I'm guessing that since you are grouping by the total amount of an order, it should also give the sum of the items quantities. So the SQL should be like so:
select c.first_name, c.last_name, sub2.order_id, sub2.shipped_date, sub2.quantities, sub2.total_amount from customers AS c
INNER JOIN(
select o.order_id, o.shipped_date, o.order_status, o.customer_id, sub1.total_price as total_amount, sub1.total_quantities FROM orders as o
INNER JOIN (
SELECT oi.order_id,SUM(oi.quantity) as total_quantities, SUM((oi.list_price * oi.quantity) - ((oi.list_price * oi.quantity) * (oi.discount))) AS total_price
FROM order_items AS oi
group by oi.order_id
) AS sub1
ON o.order_id = sub1.order_id
WHERE
sub1.total_price > 14000
AND
o.order_status = 4
) AS sub2
ON c.customer_id = sub2.customer_id group by sub2.order_id;

MySQL Sum from Alias Table

I have this query...
CREATE VIEW CustOrderItems AS
SELECT CustFirstName, CustLastName, OrderNumber, OrderDate, ShipDate,
QuantityOrdered * QuotedPrice AS ItemTotal
FROM Customers NATURAL JOIN Orders NATURAL JOIN Order_Details;
After grouping the orders like this...
SELECT CustFirstName, CustLastName, OrderNumber, OrderDate, ShipDate,
QuantityOrdered * QuotedPrice AS ItemTotal
FROM Customers NATURAL JOIN Orders NATURAL JOIN Order_Details
GROUP BY OrderNumber
ORDER BY OrderNumber ASC;
I know need to calculate the sum of all the ItemTotal's added together?
Any help is much appreciated!
As has been mentioned in a comment already, you get sums in SQL with SUM, which should not be much of a surprise. It seems strange you know about GROUP BY, but not about SUM.
At this point I'd like to recommend to always aggregate before joining, not afterwards. You want orders with their customer information and their total price. So select from orders, join with customers, join with total prices. Once you want aggregates from different tables, this approach will save you some trouble.
SELECT
c.CustFirstName,
c.CustLastName,
o.OrderNumber,
o.OrderDate,
o.ShipDate,
od.OrderTotal
FROM Orders o
JOIN Customers c ON c.CustomerNumber = o.CustomerNumber
JOIN
(
SELECT
OrderNumber,
SUM(QuantityOrdered * QuotedPrice) AS OrderTotal
FROM Order_Details
GROUP BY OrderNumber
) od ON od.OrderNumber = o.OrderNumber
ORDER BY o.OrderNumber ASC;

MySQL get top 3 suppliers from table

Hey guys I have an question that I need some support on.
I am trying to get the top 3 suppliers with a single query from a table.
This is the original question: Who are the top three suppliers by revenue, and where are they located?
Here is the online table and a query you have to run to create a new table.
http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
CREATE TABLE ByCustomerOrders AS
SELECT
o.OrderID
, p.ProductName
, p.ProductID
, Price
, Quantity
, Price * Quantity AS subtotal
, c.CustomerID
, s.SupplierID
FROM OrderDetails AS od
LEFT JOIN Orders AS o ON od.OrderID = o.OrderID
LEFT JOIN Products AS p ON p.ProductID = od.ProductID
LEFT JOIN Customers AS c on c.CustomerID = o.CustomerID
LEFT JOIN Suppliers AS s ON s.SupplierID = p.SupplierID;
From that, it creates a new table I need to list just the top 3 suppliers, pretty much the supplierID row value that shows up the most.
Some help would be appreciated.
If you want to get the 3 top suppliers by revenue (and revenue is the sum of all subtotals) this should work:
SELECT s.*, SUM(co.subtotal) as revenue
FROM ByCustomerOrders co
INNER JOIN Suppliers s ON co.SupplierID = s.SupplierID
GROUP BY co.SupplierID
ORDER BY revenue DESC
LIMIT 3;
PS: You should consider using decimal (instead of float or double) for columns that will represent money or you'll get precision errors and your numbers won't add up.
You have a fairly complex schema that you haven't completely disclosed, so this is a guess.
SELECT COUNT(s.SupplierID) AS supplier_count,
SUM(Price * Quantity) AS supplier_subtotal,
s.SupplierID,
s.SupplierName /*this is a guess*/
FROM OrderDetails AS od
LEFT JOIN Orders AS o ON od.OrderID = o.OrderID
LEFT JOIN Products AS p ON p.ProductID = od.ProductID
LEFT JOIN Customers AS c on c.CustomerID = o.CustomerID
LEFT JOIN Suppliers AS s ON s.SupplierID = p.SupplierID
GROUP BY s.SupplierID, s.SupplierName
ORDER BY COUNT(s.SupplierID) DESC
LIMIT 3
This should give you the top suppliers (by units ordered).
The trick here is to use an aggregate query (SUM() ... GROUP BY) and then order by one of the aggregate values with a DESCending qualifier.
You might want to troubleshoot this query by leaving off the LIMIT clause until you're sure you're getting the right information.

mysql sum total number of rows by customerid show desc order

I have a question my professor gave me, on making a statement that goes like this
How many customers are “whales” i.e., have spent, in their lifetime, more than $4,000? How many are “shrimps,” having spent less than $20?
This is the online database we are using: http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_all
run this query to create another table before helping me out if you can
CREATE TABLE ByCustomerOrders AS
SELECT
o.OrderID
, p.ProductName
, p.ProductID
, Price
, Quantity
, Price * Quantity AS subtotal
, c.CustomerID
, s.SupplierID
FROM OrderDetails AS od
LEFT JOIN Orders AS o
ON od.OrderID = o.OrderID
LEFT JOIN Products AS p
ON p.ProductID = od.ProductID
LEFT JOIN Customers AS c
on c.CustomerID = o.CustomerID
LEFT JOIN Suppliers AS s
ON s.SupplierID = p.SupplierID;
I am trying to combine every customers order together grouping the sum by the customerID and then showing it in the table as a row for each customer ID and total amount they have order from subtotal
SELECT customerID, SUM(subtotal) AS 'total_money_spent' FROM ByCustomerOrders GROUP BY customerID ORDER BY 'total_money_spent' DESC LIMIT 1;
That didn't seem to work as it shows a value of 111. anyone see an issue?
You have a LIMIT 1 at the end of your statement which will only show the first result.
When you run:
SELECT customerID, SUM(subtotal) AS 'total_money_spent' FROM ByCustomerOrders GROUP BY customerID ORDER BY 'total_money_spent' DESC;
It outputs all the totals grouped