I am trying to list all customers’ names with each product that customer has ordered and include customers who don't have an order. Also If a customer has ordered the same product multiple times, only list the product once for that customer.
I have the beginning of the query set up so its showing all customers and each product ordered but I can't seem to figure out how to add customers with NULL value ( meaning they haven't ordered an item.) I know left outer join is supposed to be used somehow. This is what I have so far:
select distinct
c.customerName, p.productName
from
products p, customers c, orders o, orderDetails d
left join
When using a left join a syntax like:
select distinct
c.customerName, p.productName
from customers c
left join order o on c.id = o.customer_id
left join orderDetails d on o.id = d.order_id
left join products p on p.id = d.product_id AND
p.productName = 'cow'
Related
I am trying to solve the following query, there's a few additional parameters, but these are the main attributes required:
Provide the product details, which vendors supply these products, and what was the last date these products were ordered by customers.
I have my original query below which gets me 90% of the way. I just can't seem to figure out how to display the last order date by customer per individual product. I've tried embedding (select max(o.OrderDate) from orders as o) into my select statement, but it only displays the latest order date of all of the products, not the individual per product last order date (e.g., all dates listed are 01/01/2020 when I know other products' last order date was before this date).
Apologies, I do not have enough rep to post pictures in line with text, therefore I have attached pictures of table structure and my query.
SQL Query
Table structure
Query:
select distinct p.ProductNumber, p.ProductName, p.RetailPrice, p.QuantityOnHand, v.VendName,
(select max(o.OrderDate)
from orders as o)
as LastOrderDateByCust
from ((((orders as o
inner join order_details as od
on od.OrderNumber = o.OrderNumber)
inner join products as p
on p.ProductNumber = od.ProductNumber)
inner join product_vendors as pv
on p.ProductNumber = pv.ProductNumber)
inner join vendors as v
on pv.VendorID = v.VendorID)
where p.QuantityOnHand < '10'
order by LastOrderDateByCust DESC;`
figured it out on my own I believe:
select distinct p.ProductNumber, p.ProductName, c.CategoryDescription, p.RetailPrice, pv.WholesalePrice, p.QuantityOnHand, v.VendName, pv.DaysToDeliver, (select max(o.OrderDate)
from orders as o
inner join order_details as od
on o.OrderNumber = od.OrderNumber
where od.ProductNumber = p.ProductNumber)
as LastOrderDateByCust
from (((((orders as o
inner join order_details as od
on o.OrderNumber = od.OrderNumber)
inner join products as p
on p.ProductNumber = od.ProductNumber)
inner join product_vendors as pv
on p.ProductNumber = pv.ProductNumber)
inner join vendors as v
on pv.VendorID = v.VendorID)
inner join categories as c
on p.CategoryID = c.CategoryID)
where od.ProductNumber = p.ProductNumber and p.QuantityOnHand < '10'
order by p.ProductNumber;`
I'm new to MySQL. I created a view as orders to get order data.
I want to return all the order information but it only returns the orders where the discount has been applied. My code is below.
CREATE VIEW orders
AS SELECT order_number, staff_name, manufacturer, o.product_id, product_name, quantity,
o.delivery_address, discount_percentage, price*quantity AS Total
FROM order_detail AS o INNER JOIN delivery AS d ON d.delivery_number = o.delivery_number
INNER JOIN staff AS s ON d.staff_id = s.staff_id
INNER JOIN vehicle AS v ON s.staff_id = v.staff_id
INNER JOIN product AS p ON o.product_id = p.product_id
INNER JOIN discount AS e ON e.discount_name = o.disocunt_name;
It gets an answer like
While that answer is correct I want all the orders to return not just orders with discounts. Please Help.
Use left joins. Start with the table you want to keep all of -- orders_detail:
SELECT o.order_number, staff_name, manufacturer, o.product_id, product_name, quantity,
o.delivery_address, discount_percentage, price*quantity AS Total
FROM order_detail o LEFT JOIN
delivery d
ON d.delivery_number = o.delivery_number LEFT JOIN
staff s
ON d.staff_id = s.staff_id LEFT JOIN
vehicle v
ON s.staff_id = v.staff_id LEFT JOIN
product p
ON o.product_id = p.product_id LEFT JOIN
discount e
ON e.discount_name = o.discount_name;
Note: You should qualify all column references.
I'm trying to calculate the total purchase amount of each customer from the database available online on W3 Schools
The tables I'm using are:
Customers
Orders
Products
OrderDetails
My current query gives me the product wise purchase amount for the customer. What I need is the total purchase amount.
SELECT c.CustomerID,o.OrderID,(ord.Quantity*p.Price) as
Total_Amount
from Customers c inner join Orders o
inner join Products p
inner join OrderDetails ord
on c.CustomerID = o.CustomerID
and o.OrderID = ord.OrderID
and ord.ProductID = p.ProductID;
My Output:
I need the sum for the values with the same order id and customer id.
I tried out group-by and sum but it gives me the overall sum of all the products.
You simply want a GROUP BY:
SELECT c.CustomerID, SUM(ord.Quantity*p.Price) as
Total_Amount
FROM Customers c inner join Orders o
on c.CustomerID = o.CustomerID join
OrderDetails ord
on o.OrderID = ord.OrderID join
Products p
on ord.ProductID = p.ProductID
GROUP BY CustomerID;
Note that this orders the JOINs so the ON clauses are interleaved. This is how JOINs are normally written.
If you need the sum for the values with the same order id and customer id, then you need to group the rows based on both customer id and order id.
SELECT c.CustomerID,o.OrderID,SUM(ord.Quantity*p.Price) as Total_Amount
from Customers c inner join Orders o
inner join Products p
inner join OrderDetails ord
on c.CustomerID = o.CustomerID
and o.OrderID = ord.OrderID
and ord.ProductID = p.ProductID
Group By c.CustomerID,o.OrderID
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.
Can anybody help me with this query ?
I have 3 tables : orders, customers and products.
I need to have a list of the number of orders for each customer + for each product.
Like this:
Customer A Product X 4
Customer A Product Y 0
Customer A Product Z 0
Customer B Product X 2
Customer B Product Y 0
Customer B Product Z 1
Customer C Product X 0
Customer C Product Y 0
Customer C Product Z 8
I tried a query like this :
SELECT c.Name, p.Name, COUNT(o.OrderID)
FROM orders AS o
RIGHT JOIN customers AS c ON c.CustomerID=o.CustomerID
RIGHT JOIN products AS p ON p.ProductID=o.ProductID
GROUP BY c.Name, p.Name
but I can't get it to work !
It only displays the combinations where the counter>0 (where there are records in 'orders'). But with only 1 join it DOES work, and then it DOES correctly display the records with a counter of 0. (In this example there are no products Y sold, but I do want to see Y in the list of combinations)
Any ideas?
Use a cross join. This is Oracle SQL, so not sure if it'll work for mysql.
select c.Name, p.Name, count(o.orderid)
from customers c cross join products p
left join orders o on c.customerid=o.CustomerID and p.ProductID=o.ProductID
GROUP BY c.Name, p.Name
order by c.name, p.name
You want to use outer joins and have the customers be the left side of the query, then the orders to be the left side of the remaining query, because it's the customers then orders you want to group by.
I prefer left outer joins because they map better to what you actually mean:
SELECT c.Name, p.Name, COUNT(o.OrderID)
FROM customers c
left outer join orders o ON c.CustomerID=o.CustomerID
left outer join products p ON p.ProductID=o.ProductID
GROUP BY c.Name, p.Name
select c.Name, p.Name, sum(case when o.ProductId is not null then 1 else 0 end)
from customers c,products p
left join orders o on c.CustomerID=o.CustomerID and p.ProductID=o.ProductID
GROUP BY c.Name, p.Name
If it still does not work you can do like this, which should be an equivalent
select c.Name, p.Name, sum(case when o.ProductId is not null then 1 else 0 end)
from customers c
join products p on 1=1
left join orders o on c.CustomerID=o.CustomerID and p.ProductID=o.ProductID
GROUP BY c.Name, p.Name
(I am guessing here .. as I said I have no sql at hand)