This is my target table
retail_id month tgt_volume product_type
1 2013-11-01 2 Bar
2 2013-10-01 1 Touch
3 2013-09-01 1 Bar
4 2013-10-01 5 Smart
5 2013-10-01 8 Bar
3 2013-08-01 2 Smart
2 2013-08-01 5 Bar
3 2013-07-01 7 Bar
3 2013-07-01 2 Smart
I need this format
retail_id bar smart touch total month
1 2 0 0 2 2013-11-01
2 0 0 1 1 2013-10-01
2 5 0 0 5 2013-08-01
3 1 0 0 1 2013-09-01
3 0 2 0 2 2013-08-01
3 7 2 0 9 2013-07-01
4 0 5 0 5 2013-08-01
5 8 0 0 8 2013-10-01
So I want to retrieve every months total target and each product type total for each retail_id. I was trying a query which count every product_type but not count each month. How can I do this to make above format.. my test query is(without month count)
SELECT DISTINCT t.retail_id,bar_vol.bar,smart_vol.smart,touch_vol.touch,total.total,t.month FROM targets t
LEFT JOIN
(SELECT SUM(tgt_volume) AS bar,retail_id FROM targets t1 WHERE t1.product_type='Bar' GROUP BY retail_id) AS bar_vol
ON t.retail_id=bar_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS smart,retail_id FROM targets t2 WHERE t2.product_type='Smart' GROUP BY retail_id) AS smart_vol
ON t.retail_id=smart_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS touch,retail_id FROM targets t3 WHERE t3.product_type='Touch' GROUP BY retail_id) AS touch_vol
ON t.retail_id=touch_vol.retail_id
LEFT JOIN
(SELECT SUM(tgt_volume) AS total,retail_id FROM targets t4 GROUP BY retail_id) AS total
ON t.retail_id=total.retail_id
You can use a CASE statement inside an aggregate function to achieve this:
SELECT Retail_ID,
SUM(CASE WHEN product_Type = 'Bar' THEN tgt_Volume ELSE 0 END) AS Bar,
SUM(CASE WHEN product_Type = 'smart' THEN tgt_Volume ELSE 0 END) AS Smart,
SUM(CASE WHEN product_Type = 'Touch' THEN tgt_Volume ELSE 0 END) AS Touch,
SUM(tgt_Volume) AS Total,
Month
FROM targets
GROUP BY RetailId, Month;
Example on SQL Fiddle
Related
I want to answer the following question using the below Mysql tables.
How many days were the user active on avg. (had an action) in the last
week?
I want to Display user Avg by day,
where
((user action is not 0)/unique day) in the last 7 days.
0 means the user is not active and 1 means active.
I am still a newbie in SQL and here is what I have tried so far. I am not really sure of my answers.
SELECT u.username, COUNT(u.snapshot_date) as 'active_days', a.action
FROM actions a
JOIN users u
ON a.user_id = u.user_id
WHERE NOT (a.action = 0)
GROUP BY u.username;
my output
username active_days action
Albert 2 1
Paul 4 1
Ronaldo 2 1
Messi 1 1
users table
user_id username snapshot_date
1 Albert 2022-01-10
2 Paul 2022-01-10
3 Blessing 2022-01-10
4 Ronaldo 2022-01-22
5 Messi 2022-01-01
action table
action_id action snapshot_date user_id
1 0 2022-01-10 1
2 1 2022-01-10 2
3 0 2022-01-10 3
4 1 2022-01-22 4
5 1 2022-01-01 5
6 0 2022-01-10 2
7 0 2022-01-10 1
8 0 2022-01-10 3
9 0 2022-01-22 2
10 0 2022-01-01 4
11 0 2022-01-10 2
12 1 2022-01-10 1
13 0 2022-01-10 3
14 1 2022-01-22 2
15 1 2022-01-01 4
16 1 2022-01-10 2
17 1 2022-01-10 2
18 0 2022-01-10 1
19 1 2022-01-22 1
20 0 2022-01-01 5
Average of last week
Since there are 7 days, you can divide the count by 7
SELECT u.username, COUNT(u.snapshot_date) / 7 as active_days, 1 as action
FROM actions a
JOIN users u
ON a.user_id = u.user_id
WHERE NOT (a.action = 0)
GROUP BY u.username, u.snapshot_date;
For the second problem you can average the sum of action:
SELECT u.username, SUM(a.action) / 7 as action_days, 1 as action
FROM actions a
JOIN users u
ON a.user_id = u.user_id
WHERE NOT (a.action = 0)
GROUP BY u.username, u.snapshot_date;
I'm going to do monthly COUNT.
I want to COUNT the data from now to 15 months ago.I want it to be marked 0 in the month when there is no data.
Here is My Table
PeopleFruit
Id
Fruit
People
CreatedAt
1
Apple
John
2020-11-13
2
Banana
Katie
2020-11-25
3
Kiwi
Sam
2021-03-03
4
Apple
Katie
2021-04-12
5
Apple
Katie
2021-04-24
6
Apple
John
2021-04-30
7
Banana
Sam
2021-09-02
8
Banana
Katie
2021-11-11
9
Apple
Sam
2021-12-12
10
Kiwi
John
2021-12-15
I want to know the fruit COUNT by month so that people don't overlap.
ex)If you look at Apple in April(Month 4), Katie chose it twice and John chose it once, but because Katie overlaps, COUNT became 2.
I used this query.
SELECT DATE_FORMAT(createdAt,'%y.%m') m, COUNT(DISTINCT(People)) as count
FROM PeopleFruit
WHERE createdAt > DATE_ADD(NOW(),INTERVAL - 15 MONTH)
AND Fruit = 'Apple'
GROUP BY m;
result is
m
count
20.11
1
21.04
2
21.12
1
But this is the result I want.
m
count
21.12
1
21.11
0
21.10
0
21.09
0
21.08
0
21.07
0
21.06
0
21.05
0
21.04
2
21.03
0
21.02
0
21.01
0
20.12
0
20.11
1
20.10
0
What should I do?
Since MySQL 8.0 you can use RECURSIVE CTE like:
WITH RECURSIVE months(m) AS (
SELECT DATE_FORMAT(NOW(),'%Y-%m-01') m
UNION ALL
SELECT DATE_SUB(m, INTERVAL 1 MONTH) m FROM months
WHERE m > DATE_SUB(NOW(), INTERVAL 15 MONTH)
) SELECT
DATE_FORMAT(months.m,'%y.%m') m,
COALESCE(count, 0) count
FROM months
NATURAL LEFT JOIN (
SELECT DATE_FORMAT(createdAt,'%Y-%m-01') m, COUNT(DISTINCT(People)) as count
FROM PeopleFruit
WHERE createdAt > DATE_ADD(NOW(),INTERVAL - 15 MONTH) AND Fruit = 'Apple'
GROUP BY m
) months_count ;
MySQL recursive CTE test
I have 1 table called itemmovement : It has Item Id , Quantity In , Quantity Out , Invoice Id, Date. I need to make in one query to show how many pieces are sold and beside the sold column there will be the current on hand quantity .
itemmovement
Id itemid qtyin qtyout invid purchasereturnid date
1 1 10 2019-01-04
2 2 8 2019-01-06
3 2 2 1 2019-01-08
4 1 3 2 2019-01-12
5 2 1 2019-02-04
6 3 4 2019-03-04
7 1 1 3 2019-04-04
8 1 1 1 2019-04-14
9 3 1 2 2019-04-24
I need the query to show this result
Id itemid Sold Quantity OnHandQty
1 1 4 5
2 2 2 7
3 3 0 3
I'm Trying to use this query but not working
SELECT *
FROM
(SELECT itmv.itemid,
sum(itmv.qtyout)-sum(itmv.qtyin)
FROM itemmovement itmv
WHERE (itmv.systemdate BETWEEN '2019-01-01' AND '2019-06-01')
AND invid>0
GROUP BY itmv.itemid) AS result1,
(SELECT sum(itmv2.qtyin)-sum(itmv2.qtyout)
FROM itemmovement itmv2
WHERE itmv.itemid=itmv2.itemid
GROUP BY itmv2.itemid) AS result2
ORDER BY sum(itmv.qtyin)-sum(itmv.qtyout)
I'm getting :
Unknown column 'itmv.itemid' in 'where clause it for this syntax :
where itmv.itemid = itmv2.itemid
Here's your query.
select itemid
, sum(case when COALESCE(invid,0) > 0 then qtyout else 0 end) as Sold_Qantity
, sum(qtyin)-sum(qtyout) as OnHandQty
from itemmovement
group by itemid
I want to get the date of this week and the total sum of total_price even there is no transaction on the specific date. The problem is when I change the value of tbl_barangay.city_id into 2, all the data of tbl_barangay.city_id = 1 is included. I want to get all records according to the value of tbl_barangay.city_id. How can I left join more than 2 tables so I can get the expected data?
Sample data
tbl_calendar tbl_city tbl_tran
date_id date city_id city_name tran_id tran_date city_id
1 2019-08-19 1 Sala 1 2019-08-19 1
2 2019-08-20 2 Marinig 2 2019-08-20 1
3 2019-08-21 3 Pulo 3 2019-08-23 2
4 2019-08-22
5 2019-08-23
6 2019-08-24
7 2019-08-25
tbl_tran_details
detail_id item total_price tran_id
1 Item1 20 1
2 Item2 20 1
2 Item3 30 2
2 Item1 30 3
Expected data if the tbl_city.city_id = 1
Date Total
2019-08-19 40
2019-08-20 30
2019-08-21 0
2019-08-22 0
2019-08-23 0
2019-08-24 0
and if the tbl_city.city_id = 2
Date Total
2019-08-19 0
2019-08-20 0
2019-08-21 0
2019-08-22 0
2019-08-23 30
2019-08-24 0
SELECT tbl_calendar.date Date,
SUM(IFNULL(tbl_tran_details.total_price,0)) Total FROM tbl_calendar
LEFT JOIN
tbl_tran ON tbl_calendar.date = tbl_tran.tran_date
LEFT JOIN
tbl_tran_details ON tbl_tran.tran_id = tbl_tran_details.tran_id
LEFT JOIN
tbl_city ON tbl_tran.city_id = tbl_city.city_id AND tbl_city.city_id = 2
WHERE
YEAR(tbl_calendar.date) = YEAR(NOW())
AND
WEEK(tbl_calendar.date) = WEEK(NOW())
GROUP BY
tbl_calendar.date
The problem is that you filter the cities in the wrong table because you want to get the sum of transactions for a certain city from the tbl_tran table, but you filter the cities in the tbl_city - which you do not even use in this query.
...
FROM (tbl_calendar
LEFT JOIN
tbl_tran ON tbl_calendar.date = tbl_tran.tran_date AND tbl_tran.city_id = 2)
LEFT JOIN
tbl_tran_details ON tbl_tran.tran_id = tbl_tran_details.tran_id
...
I have a mysql table like this:
id course_id amount created_on
1 2 100 2018-01-03
2 1 300 2018-03-03
3 2 200 2018-01-03
4 4 400 2018-04-03
I would like to pass the course id and get total amount for that course donated for a year, based on month wise. If no donation is made for a month need to show it as 0
output as below:
month amount
1 300
2 0
3 200
4 400
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
You need a calendar month table for this, because there is no guarantee that your current table has data for every month.
SELECT
t1.month,
COALESCE(t2.amount, 0) AS amount
FROM
(
SELECT 1 AS month UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9 UNION ALL
SELECT 10 UNION ALL
SELECT 11 UNION ALL
SELECT 12
) t1
LEFT JOIN
(
SELECT MONTH(created_on) AS month, SUM(amount) AS amount
FROM yourTable
GROUP BY MONTH(created_on)
) t2
ON t1.month = t2.month
ORDER BY
t1.month;