MYSQL getting total of summed column - mysql

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

Related

MYSQL I need to query info from multiple tables using JOIN

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;

Average days between first and second purchase

can someone assist with the following. I need to figure out what the average day difference is between the first and second purchase of a customer:
I have the below: can someone assist with with my query please.
SELECT src.id, AVG(DATEDIFF(dest.purchasing, src.registrations)) AS avgdays FROM
(SELECT accounts.id, accounts.`created_date` AS registrations FROM accounts
WHERE YEAR(accounts.`created_date`) =2018 AND MONTH(accounts.`created_date`) =4) src
INNER JOIN
(SELECT account_id, MIN(created_date) AS purchasing
FROM ordering
WHERE STATUS = 'Fulfilled'
GROUP BY account_id
) dest
ON
dest.account_id = src.id;
The below query will give you the average difference between 2nd purchase if customer registration date is also his first order purchase date.
select account_id,customer_created,
avg(DATEDIFF(order_created, customer_created)) from
(select a.account_id,b.created_at as order_created, a.created_at
customer_created from
(select * from accounts where YEAR(created_at) =2018 AND
MONTH(created_at) =4) a
INNER JOIN ordering b on a.account_id=b.account_id where
b.status="Delivered" ) a
where customer_created <> order_created GROUP BY a.account_id ;

Select from one table with count from two other tables

I'm doing a query where i select all from a table called employee and want to do a count of employee_id from two other tables and represent the count in 2 seperate columns.
The tables:
employee [id, etc.]
report [id, employee_id, etc.]
office_report[id, employee_id, etc.]
What i did so far is:
SELECT emp.*, COUNT(rep.id ) no_of_field_reports, COUNT(of_rep.id) no_of_office_reports
FROM employee emp
LEFT JOIN report rep
ON (emp.id = rep.employee_id)
LEFT JOIN office_report of_rep
ON (emp.id = of_rep.employee_id)
WHERE emp.user_id =7 AND emp.active = 1
GROUP BY emp.id, emp.name
ORDER BY emp.name ASC
The problem is, as soon as i have reports in BOTH report tables the count messes up. Say i have 16 reports in report table and 2 in office_report table, the count for no_of_field_reports and no_of_office_reports will become 32.
Im missing something obviously but as I'm not a SQL genius I can't figure out what.
Please make sure to explain what is causing the problem so I'm able to learn from my mistakes and get a better understanding of these type of queries as this is not going to be the last time.
I guess the answer will be the same for mariaDB, mySQL, and SQL in general so i added all those tag's for the sake of attention..
Possibly one approach if you're after distinct counts ( though you may need to adjust to the PK field)
SELECT emp.*,
COUNT(distinct rep.id ) no_of_field_reports, --may need to be on Unique key instead
COUNT(distinct of_rep.id) no_of_office_reports --may need to be on Unique key instead)
FROM employee emp
LEFT JOIN report rep
ON (emp.id = rep.employee_id)
LEFT JOIN office_report of_rep
ON (emp.id = of_rep.employee_id)
WHERE emp.user_id =7 AND emp.active = 1
GROUP BY emp.id, emp.name
ORDER BY emp.name ASC
An approach getting the counts before the joins if you're not after a distinct count then this is likely the right approach and offers flexibility.
SELECT emp.*, rep.cnt, of_Rep.cnt
FROM employee emp
LEFT JOIN (SELECT count(ID) cnt , employee_ID
FROM REPORT
GROUP BY employee_ID) rep
ON (emp.id = rep.employee_id)
LEFT JOIN (SELECT count(ID) cnt, Employee_ID
FROM office_report
GROUP BY employee_ID) of_rep
ON (emp.id = of_Rep.employee_id)
WHERE emp.user_id =7 AND emp.active = 1
GROUP BY emp.id, emp.name
ORDER BY emp.name ASC
or use of correlated queries (but not supported all the time Such as when creating materialized views from this SQL)
SELECT emp.*,
(SELECT count(ID)
FROM REPORT
WHERE emp.id = rep.employee_id) Report_Cnt,
(SELECT count(ID)
FROM office_report of_REP
WHERE emp.id = of_Rep.employee_id) of_Rep_Cnt
FROM employee emp
WHERE emp.user_id =7 AND emp.active = 1
GROUP BY emp.id, emp.name
ORDER BY emp.name ASC

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;

Calculate Sum() but excluding JOIN

In the sales table, there is a point field. I want to sum(point) when grouping by sales.submit_date but that wont add up correctly because it will duplicate the records from JOIN
SELECT
COUNT(DISTINCT sales.sales_id) as TotalSales,
COUNT(DISTINCT sales_lines.id) as TotalLiness
FROM `sales`
JOIN sales_lines ON sales_lines.sales_id = sales.sales_id
GROUP BY sales.submit_date
SQL above, this will count the number of sales in the sales table and also count number of lines in the sales_lines (number of lines matched to sales_lines.sales_id = sales.sales_id). This seem to work fine.
How do I sum(`sales.point') in the sales only?
You could aggregate sales_lines up to the sales grain.
SELECT
S.submit.date,
,sum(s.point)
,COUNT(s.sales_id) as TotalSales
,SUM(SL.SalesLines) as TotalLines
FROM
sales S
INNER JOIN
(Select
sales_id
,count(distinct id) as SalesLines
FROM
sales_lines
GROUP BY
sales_id) SL
ON S.sales_id = SL.sales_id3
GROUP BY
s.submit_date