MYSQL I need to query info from multiple tables using JOIN - mysql

I need to get the customer state, book name, order count and revenue from tables named order_line_items (contains the order quantity), orders (contains the revenue), customers (contains the state) and books (contains book name) . So far I have:
SELECT
YEAR(purchased_at) AS year_purchased,
COUNT(*) order_count,
COUNT(DISTINCT customer_id) customer_count,
CONCAT('$', FORMAT(SUM(total), 2)) AS revenue
FROM
orders
GROUP BY
year_purchased
ORDER BY
year_purchased;
the code above works fine but is not complete, when I add the rest of what I need I get a wrong total for count and revenue. This is giving me issues:
SELECT
YEAR(purchased_at) AS year_purchased,
COUNT(*) order_count,
COUNT(DISTINCT customer_id) customer_count,
CONCAT('$', FORMAT(SUM(total), 2)) AS revenue,
state,
collection
FROM
customers c
JOIN books
JOIN orders o ON c.id = o.customer_id
GROUP BY
year_purchased,
state,
collection
ORDER BY
year_purchased,
state,
collection LIMIT 4;

Related

Trying to make a new table by pulling data from two tables and keep getting 'Error: Every derived table must have its own alias' on this query

I have an 'Orders' table and a 'Records' table.
Orders table has the following columns:
order_id order_date seller order_price
Records table has the following columns:
order_id record_created_at record_log
I'm trying to pull and compile the following list of data but I keep getting an error message:
order_week
seller
total_num_orders
under100_count --this is the number of orders that were < $100
over100_count --this is the number of order that >= $100
approved --this is the number of orders that were approved by the payment platform
Here's my query:
SELECT order_week, seller, total_num_orders, under100_count, over100_count, approved
FROM (
SELECT
EXTRACT(WEEK FROM order_created_at) AS order_week,
merchant_name AS seller,
COUNT(merchant_name) AS total_num_orders,
SUM(DISTINCT total_order_price < 100) AS under100_count,
SUM(DISTINCT total_order_price >= 100) AS over100_count
FROM orders o
GROUP BY order_week, seller)
INNER JOIN (
SELECT
COUNT(DISTINCT o.order_id) AS approved
FROM records r
WHERE record_log = 'order approved'
GROUP BY order_id)
ON l.order_id = o.order_id;
What am I doing wrong?
The subquery in the join needs an alias. It also needs to return the order_id column, so it can be joined.
inner join ( select order_id, ... from records ... group by order_id) r --> here
on l.order_id = o.order_id
I would actually write your query as:
select
extract(week from o.order_created_at) as order_week,
o.merchant_name as seller,
count(*) as total_num_orders,
sum(o.total_order_price < 100) as under100_count,
sum(o.total_order_price >= 100) as over100_count,
sum(r.approved) approved
from orders o
inner join (
select order_id, count(*) approved
from records r
where record_log = 'order approved'
group by order_id
) r on r.order_id = o.order_id;
group by order_week, seller, approved
Rationale:
you don't want, and need, distinct in the aggregate functions here; it is inefficient, and might even yield wrong results
count(*) is more efficient count(<expression>) - so, use it, unless you know why you are doing otherwise
I removed an unecessary level of nesting
If there are orders without records, you might want a left join instead.

MYSQL getting total of summed column

have this problem for a school example problem where I have to get the total salary for coaches and participants in March (done below) and then I have to sum to get the total salary due in March for all employees which I just want to add onto the end of the Total Salary column.
This is what I have so far:
(SELECT Coach.name AS Name, COUNT(*) AS 'Shows Attended In March',
dailySalary AS 'Daily Salary', sum(dailySalary) AS 'Total Salary'
FROM Coach, TVShow, CoachInShow
WHERE monthname(dateOfShow)='March' AND
Coach.idCoach=CoachInShow.idCoach AND TVShow.idShow =
CoachInShow.idShow
GROUP BY Coach.name, Coach.dailySalary)
UNION
(SELECT Participant.name AS Name, COUNT(*) AS 'Shows Attended In
March', dailySalary AS 'Daily Salary', sum(dailySalary) AS 'Total
Salary'
FROM Participant, TVShow, Contender, ContenderInShow
WHERE monthname(dateOfShow)='March' AND Participant.idContender =
Contender.idContender AND Contender.idContender =
ContenderInShow.idContender AND ContenderInShow.idShow = TVShow.idShow
GROUP BY Participant.name, Participant.dailySalary);
I tried using GROUP BY WITH ROLLBACK on the whole thing but it doesn't add up only the TotalSalary columns. I've spent a while on this and kinda stumped.
I pasted the data here for what I'm working with: https://www.db-fiddle.com/f/gPKVQrZCMkvHUqViAUzCqZ/0 http://sqlfiddle.com/#!9/535f6d/1
Put the UNION into a subquery. In the main query, sum all the counts and total salaries, and use WITH ROLLUP to get the grand total.
You don't need dailySalary in the GROUP BY clause, since it's functionally dependent on the ID.
SELECT name AS Name, SUM(count) AS `Shows Attended in March`, SUM(totalSalary) AS `Total Salary`
FROM (
SELECT Coach.name, COUNT(*) AS count, SUM(dailySalary) AS totalSalary
FROM Coach
JOIN CoachInShow ON Coach.idCoach=CoachInShow.idCoach
JOIN TVShow ON TVShow.idShow = CoachInShow.idShow
WHERE monthname(dateOfShow)='March'
GROUP BY Coach.idCoach
UNION
SELECT Participant.name, COUNT(*) AS count, SUM(dailySalary) AS totalSalary
FROM Participant
JOIN Contender ON Participant.idContender = Contender.idContender
JOIN ContenderInShow ON Contender.idContender = ContenderInShow.idContender
JOIN TVShow ON ContenderInShow.idShow = TVShow.idShow
WHERE monthname(dateOfShow)='March'
GROUP BY Participant.idParticipant
) AS x
GROUP BY Name
WITH ROLLUP
DEMO

sql query questions based on w3 schools

List customers for each category and the total of order placed by that customer in a given category. In the query show three columnm: CategoryName, CustomerName, and TotalOrders (which is price * quantity for orders for a given customer in a given category). Sort this data in descending order by TotalOrders.
should be this ...
select category, customer, sum(price*quantity) as TotalOrders
from yourTable
group by category, customer
order by TotalOrders desc;

Sum function returns only one level of hierarchy

I have table company. It stores the following data: id, title, budget, pid (parent id), total amount. It is necessary to calculate the company's budget + budget of subsidiaries. I do it in the column total.
"SELECT o.id, o.title, o.budget, o.pid,
(select sum(o1.budget)+o.budget from company o1 where o1.pid=o.id) total
FROM company o ORDER BY o.id";
This request summarizes the amount of budgets only on the level below, and I need to calculate the budgets of all the subordinate companies.
You are missing a GROUP BY, without the GROUP BY you will only get the total sum of your budget, try something like this:
SELECT o.id, o.title, o.budget, o.pid,
(select sum(o1.budget)+o.budget from company o1 where o1.pid=o.id) total
FROM company o
GROUP BY o.id
ORDER BY o.id

SQL query to compute total number of customers who purchase >4 products on one day

I want to write a SQL query to compute which customers have purchased more than 4 products on the same day.
Here are my tables:
Sales
(date, customer_id, product_id, units_sold)
Products
(id, name, price)
Customers
(id, name)
& here's what I have so far:
SELECT COUNT(s.product_id) as total_customers
FROM Sales s1
WHERE DATEDIFF(s1.date, s2.date)=0
INNER JOIN Sales s2
ON s1.product_id = s2.product_id
HAVING COUNT(s.product_id) > 4;
If you want the customers who have purchased more than 4 products on the same date:
SELECT DISTINCT s.customer_id
FROM Sales s
GROUP BY s.customer_id, date(s.date)
HAVING COUNT(*) > 4;
This is one of the few cases where SELECT DISTINCT is used with GROUP BY. If you want to know the dates as well, then include date(s.date) in the SELECT.
Note that this assumes that any given product is purchased by a customer only once on each date. If a customer can have multiple records for a single product on one date, use COUNT(DISTINCT product_id) instead of COUNT(*).
To get the total number of customers, use a subquery:
SELECT COUNT(*)
FROM (SELECT DISTINCT s.customer_id
FROM Sales s
GROUP BY s.customer_id, date(s.date)
HAVING COUNT(*) > 4
) c
Too many mistakes's in your query try this
SELECT customer_id,cast(s1.date as date),COUNT(s1.product_id) as total_customers
FROM Sales s1
Group by customer_id,cast(s1.date as date)
HAVING COUNT(s1.product_id) > 4;