inner-join mysql x3 - mysql

I need to display cust_id, the customer forename and surname, the product name<-(from products table) and date of sale<--(from sales table), also I need to display in order of the most recent dates first.
This is what I have got so far:
SELECT
customer.cust_id,
customer.forename,
customer.surname,
products.prod_name,
sales.Date_of_sale
FROM customers c
INNER JOIN sales s ON c.cust_id = s.cust_id
INNER JOIN products p ON s.product_id = p.product_id
ORDER BY s.Date_of_sale DESC
Any help would be appreciated.

This
SELECT
c.cust_id,
c.forename,
c.surname,
p.prod_name,
s.Date_of_sale
FROM customers c
INNER JOIN sales s ON c.cust_id = s.cust_id
INNER JOIN products p ON s.product_id = p.product_id
ORDER BY s.Date_of_sale DESC
will work

Related

Write an SQL Query to calculate total purchase amount of each customer

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

MySQL: Ranking from multiple tables, sub queries?

This is a MySQL question. I have three tables with the following columns:
transactions (table): transact_id, customer_id, transact_amt, product_id,
products (table): product_id, product_cost, product_name, product_category
customers (table): customer_id, joined_at, last_login_at, state, name, email
I'd like a query that finds out the most popular item in every state and the state. One of the tricky parts is that some product_name have multiple product_id. Therefore I though joining the three tables that generate an output with two columns: state and product_name. Until here that worked fine doing this:
SELECT p.product_name, c.state
FROM products p
INNER JOIN transactions t
ON p.product_id = t.product_id
INNER JOIN customers c
ON c.customer_id = t.customer_id
This selects all the products, and the states from where the customer is. The problem is that I can't find the way to rank the mos popular product per state. I tried different group by, order by and using subqueries without success. I suspect I need to do subqueries, but I can't find the way to resolve it. The expected outcome should look like this:
most_popular_product | state
Bamboo | WA
Walnut | MO
Any help will be greatly appreciated.
Thank you!
You need a subquery that gets the count of transactions for each product in each state.
SELECT p.product_name, c.state, COUNT(*) AS count
FROM products p
INNER JOIN transactions t
ON p.product_id = t.product_id
INNER JOIN customers c
ON c.customer_id = t.customer_id
GROUP BY p.product_name, c.state
Then write another query that has this as a subquery, and gets the highest count for each state.
SELECT state, MAX(count) AS maxcount
FROM (
SELECT p.product_name, c.state, COUNT(*) AS count
FROM products p
INNER JOIN transactions t
ON p.product_id = t.product_id
INNER JOIN customers c
ON c.customer_id = t.customer_id
GROUP BY p.product_name, c.state
) AS t
GROUP BY state
Finally, join them together:
SELECT t1.product_name AS most_popular_product, t1.state
FROM (
SELECT p.product_name, c.state, COUNT(*) AS count
FROM products p
INNER JOIN transactions t
ON p.product_id = t.product_id
INNER JOIN customers c
ON c.customer_id = t.customer_id
GROUP BY p.product_name, c.state
) AS t1
JOIN (
SELECT state, MAX(count) AS maxcount
FROM (
SELECT p.product_name, c.state, COUNT(*) AS count
FROM products p
INNER JOIN transactions t
ON p.product_id = t.product_id
INNER JOIN customers c
ON c.customer_id = t.customer_id
GROUP BY p.product_name, c.state
) AS t
GROUP BY state
) AS t2 ON t1.state = t2.state AND t1.count = t2.maxcount
This is basically the same pattern as SQL select only rows with max value on a column, just using the first grouped query as the table you're trying to group.

query returns more than one row

I'm trying to get the total rental amount for each client from Sakila example database
so I tried with the following query:
select customer.customer_id, customer.first_name,
(select sum(payment.amount) from customer
inner join rental on customer.customer_id=rental.customer_id
inner join payment on rental.rental_id=payment.rental_id group by payment.amount)
from customer
inner join rental on customer.customer_id=rental.customer_id
inner join payment on rental.rental_id=payment.rental_id
group by customer.customer_id;
and I get this "Subquery returns more than one row". Do you know what could be wrong? Thank you
This is your query, with some reformatting and the use of table aliases:
select c.customer_id, c.first_name,
(select sum(p2.amount)
from customer ce inner join
rental r2
on c2.customer_id = r2.customer_id inner join
payment p2
on r2.rental_id = p2.rental_id
group by p2.amount
-------^
)
from customer c inner join
rental r
on c.customer_id = r.customer_id inner join
payment p
on r.rental_id = p.rental_id
group by c.customer_id;
I've highlighted the specific cause of your problem. But the fix is to radically simplify the query:
select c.customer_id, c.first_name, sum(p.amount)
from customer c left join
rental r
on c.customer_id = r.customer_id left join
payment p
on r.rental_id = p.rental_id
group by c.customer_id;
Is that the result you're looking for?
SELECT C.customer_id
,C.first_name
,SUM(P.amount) AS [total_amount]
FROM customer C
INNER JOIN rental R ON R.customer_id = C.customer_id
INNER JOIN payment P ON P.rental_id = R.rental_id
GROUP BY C.customer_id, C.first_name
-- Condition to get only the largest amount
-- without using an ORDER BY clause
HAVING SUM(P.amount) = (SELECT MAX(SUM(P2.amount))
FROM rental R2
INNER JOIN payment P2 ON P2.rental_id = R2.rental_id
GROUP BY R2.customer_id)
Hope this will help you.

Select top sales products

I have three tables like this
orders(id, status, ...)
products(id, created_at, ...)
product_order(order_id, product_id, quantity)
I want to select the most sold products first then continue with latest products taking the quantity in consideration, Here's my try
SELECT products.* FROM products
LEFT JOIN product_order ON product_order.product_id = products.id
LEFT JOIN orders ON orders.id = product_order.order_id
WHERE orders.status != 'REJECTED'
GROUP BY product_order.product_id
ORDER BY COUNT(*) DESC, products.created_at
This statement returns the products that are not sold first because I am using left join and they count more than the sold ones.. also I don't know how to take the quantity in consideration
Thank you,
This should work :
SELECT p.*, sum(po.quantity) qty
FROM products p
LEFT OUTER JOIN product_order po ON po.product_id = p.id
LEFT OUTER JOIN orders o ON o.id = po.order_id
WHERE o.status != 'REJECTED'
GROUP BY po.product_id
ORDER BY qty DESC, p.created_at
If you want the most sold products you could add
AND products.quantity = SELECT max(quantity) from products
after your WHERE statement

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)