Complex sql query with multiple tables - mysql

I have 3 tables:
Customers
ID_CUSTOMER
NAME
Products
ID_PRODUCT
PRODUCTNAME
PRICE
Orders
ID_ORDER
CUSTOMER_ID
PRODUCT_ID
QUANTITY
How to select all customers who ordered for $10k or more?

try something like:
SELECT C.ID_CUSTOMER, C.Name,
SUM(P.PRICE * O.QUANTITY) AS Total FROM Customers C
JOIN Orders O ON C.CUSTOMER_ID = O.CUSTOMER_ID
JOIN Procucts P ON P.PRODUCT_ID = O.PRODUCT_ID
GROUP BY C.ID_CUSTOMER, C.Name
HAVING SUM(P.PRICE * O.QUANTITY) >= 10000

select c.*
from customers c
inner join orders o on o.customer_id = c.id_customer
inner join products p on p.id_product = o.product_id
group by c.id_customer
having sum(p.price * o.quantity) >= 10000

try this:
SELECT a.ID_CUSTOMER,
a.NAME
FROM CUSTOMERS a
INNER JOIN ORDERS b
ON b.CUSTOMER_ID = a.ID_CUSTOMER
INNER JOIN PRODUCTS c
ON c.ID_PRODUCT = b.product_id
GROUP BY a.ID_CUSTOMER, a.NAME
HAVING SUM(c.PRICE * b.QUANTITY) >= 10000

It is not really a complex query. Another syntax to do the same thing:
SELECT C.ID_CUSTOMER, C.NAME, SUM(P.PRICE * O.QUANTITY) TOTAL
FROM Products P, Customers C, Orders O
WHERE O.CUSTOMER_ID = C.ID_CUSTOMER
AND O.PRODUCT_ID = P.ID_PRODUCT
GROUP BY C.ID_CUSTOMER, C.NAME
HAVING SUM(P.PRICE * O.QUANTITY) >= 10000

Related

Retrieve customer who bought more than 13 different products who never purchased same product

I tried this. But I feel this gives people who ordered same product
SELECT DISTINCT Count(od.orderqty) OrderQty,
c.customerid,
od.productid
FROM sales.customer c
INNER JOIN sales.salesorderheader oh
ON c.customerid = oh.customerid
INNER JOIN sales.salesorderdetail od
ON oh.salesorderid = od.salesorderid
GROUP BY od.productid,
c.customerid
HAVING Count(od.productid) > 10
ORDER BY c.customerid
Not sure what flavor of SQL you're using but try this:
select t.CustomerID
from (
select c.CustomerID
, count(distinct od.ProductID) as DistinctCount
, count(od.ProductID) as Count
from Sales.Customer c
join Sales.SalesOrderHeader oh
on c.customerid = oh.customerid
join Sales.SalesOrderDetail od
on oh.SalesOrderID = od.SalesOrderID
group
by c.CustomerID
) as t
where t.DistinctCount = t.Count
and t.DistinctCount > 13
order
by t.CustomerID

MySQL - Using subqueries on join and from

I am trying to return the CustomerID, CompanyName, OrderID, and subtotals for each customer for all order the subtotal amounts that are higher than the customer’s average subtotal amount. These are the tables I am using and the query below. I am unsure if the values I return are correct and was hoping someone could help me understand if they are or not based on my query. Thanks in advance.
Orders
Columns
OrderID
CustomerID
EmployeeID
OrderDate
RequiredDate
OrderDetails
Columns
OrderID
ProductID
UnitPrice
Quantity
Products
Columns
ProductID
ProductName
QuantityPerUnit
UnitPrice
Customers
Columns
CustomerID
CompanyName
ContactName
Country
SELECT A.CustomerID, A.CompanyName, A.Subtotal, A.OrderID, AVGSubtotal
FROM (
SELECT
C.CustomerID,
C.CompanyName,
(D.UnitPrice * P.QuantityPerUnit) AS Subtotal,
D.OrderID
FROM Customers C
JOIN Orders O ON C.CustomerID = O.CustomerID
JOIN OrderDetails D ON D.OrderID = O.OrderID
JOIN Products P ON P.ProductID = D.ProductID
GROUP BY
D.OrderID, C.CustomerID
) A
JOIN (
SELECT
S.CustomerID, S.CompanyName, AVG(S.Subtotal) as AVGSubtotal
FROM (
SELECT
C.CustomerID,
C.CompanyName,
(D.UnitPrice * P.QuantityPerUnit) AS Subtotal
FROM Customers C
JOIN Orders O ON C.CustomerID = O.CustomerID
JOIN OrderDetails D ON D.OrderID = O.OrderID
JOIN Products P ON P.ProductID = D.ProductID
GROUP BY
D.OrderID, C.CustomerID
) S
GROUP BY
S.CustomerID
) B ON A.CustomerID = B.CustomerID
WHERE
A.CustomerID = B.CustomerID AND
A.Subtotal > B.AVGSubtotal
ORDER BY
A.CustomerID, A.CompanyName
;
select
c2.customerID,
c2.CompanyName,
c2.AVGSubtotal
o2.OrderID,
o2.UnitPrice * o2.Quantity as subtotal
from (
select
c.CustomerID,
c.CompanyName,
sum(o.UnitPrice * o.Quantity)/count(*) as AVGSubtotal
from
Customers c
inner join Orders o on (o.CustomerID = c.CustomerID)
inner join OrderDetails od on (od.OrderID = c.OrderID)
group by
o.CustomerID
) as c2
inner join Orders o2 on (o2.CustomerID = c2.CustomerID)
where o2.UnitPrice * o2.Quantity > c2.AVGSubtotal

How can I combine information from 4 different tables in a SQL query?

I have a to write an SQL query to list the names and total spend of customers who made more
than one order. The following lists all the relevant information but I'm struggling to see how to move forward with this.
SELECT l.quantity, o.orderID, i.itemID, o.custID, i.unitcost, c.familyname
FROM lineitems l, orders o, items i, customers c
WHERE l.itemID = i.itemID
AND c.custID = o.custID
AND o.orderID = l.orderID
ORDER BY o.custID
Select customerId, Sum(i.quantity*i.unitCost)
From lineitems I
join orders o on o.orderID = i.orderID
where Exists(Select * From orders
where customerId = o.customerId
having count(*) > 1)
group by customerId
or, with name instead of just customerId
Select c.familyname, Sum(i.quantity*i.unitCost)
From lineitems I
join orders o on o.orderID = i.orderID
join customers c on c.customerId = o.customerId
where Exists(Select * From orders
where customerId = o.customerId
having count(*) > 1)
group by c.familyname

Multiple inner joins to get a complex report, not working

For the schema below, I need to get this report
This is what I have
select c.name, sr.name, count(o.order_id)
from contact c
INNER JOIN accounts a
ON c.account_id=a.account_id
INNER JOIN sales_reps sr
ON a.sales_rep_id =sr.sales_rep_id
INNER JOIN orders o
ON a.account_id =o.account_id
where o.order_id in (
select SUM(oi.quantity*p.price) from
order_items oi INNER JOIN parts p
on oi.part_id =p.part_id
)
group by a.account_id, c.name
But this does not give any results.
Please help.
Your where condition is not right, how should be a order_id equal a sum?
Try the below:
select
c.name, sr.name, COUNT(o.order_id), SUM(op.order_total)
FROM
contact c
INNER JOIN
accounts a ON c.account_id = a.account_id
INNER JOIN
sales_reps sr ON a.sales_rep_id = sr.sales_rep_id
INNER JOIN
orders o ON a.account_id = o.account_id
INNER JOIN
(SELECT
oi.order_id, SUM(oi.quantity * p.price) AS order_total
FROM
order_items oi
INNER JOIN
parts p ON oi.part_id = p.part_id
GROUP BY
oi.order_id
) op ON o.order_id = op.order_id
WHERE o.delivery_data >= CURDATE()
GROUP by c.contact_id
It won't give results as your WHERE ... IN SELECT is based on a query returning a sum() value which will not equal a key (most likely), or incorrect at best... and since you are dealing with a quantity and price which will have decimal precision (typically), you won't even get that to match even LESS likely...
I would swap the query around to pre-qualify the orders within a given date in question and sum that... THEN join to rest...
select
c.name,
sr.name,
PreQualified.NumberOrders,
PreQualified.OrderTotal
from
( select
o.Account_ID,
count( distinct o.order_id ) as NumberOrders,
sum( oi.quantity * p.price ) as OrderTotal
from
orders o
join order_items oi
on o.order_id = oi.order_id
join parts p
on oi.part_id = p.part_id
where
o.Delivery_Date >= CURDATE()
group by
o.Account_ID ) as PreQualified
JOIN Accounts a
on PreQualified.Account_ID = a.Account_ID
Join Contact C
on a.Account_ID = c.Account_ID
JOIN Sales_Reps sr
ON a.sales_rep_id = sr.sales_rep_id
If you want to count records use
count(*)
Instead of
count(o.order_id)

Modify SQL query to get all users?

I currently have this query.
SELECT DISTINCT (o.customer_id), count( o.id ) AS orders, c.*
FROM `order` AS o LEFT JOIN customer AS c ON o.customer_id = c.id
GROUP BY customer_id
What it does is it returns all customers that have made an order and counts the number of orders each customer has made.
What I need to do is modify this query so it also returns those customers who haven't made an order. Do you have any idea how this would be done?
I tried to reverse the query but this didn't do the trick..
SELECT DISTINCT (o.customer_id), count( o.id ) AS orders, c.*
FROM customer AS c LEFT JOIN order AS o ON o.customer_id = c.id
GROUP BY o.customer_id
Try this.
SELECT o.customer_id, sum( case when o.id is not null then 1 else 0 end ) AS orders, c.*
FROM customer c
LEFT JOIN order o ON o.customer_id = c.id GROUP BY customer_id
What about:
SELECT DISTINCT (o.customer_id), count( o.id ) AS orders, c.*
FROM `order` AS o
LEFT OUTER JOIN customer AS c ON o.customer_id = c.id GROUP BY customer_id
SELECT o.customer_id, c.*
FROM customer AS c LEFT JOIN order AS o ON o.customer_id = c.id
WHERE o.id IS NULL
GROUP BY o.customer_id
You can also skip the "GROUP BY" clause because when the orders side is NULL, there is always only one row for the customer:
SELECT o.customer_id, c.*
FROM customer AS c LEFT JOIN order AS o ON o.customer_id = c.id
WHERE o.id IS NULL