cumulative sum till target reached in mysql - mysql

I have following tables,
Workout Data:
Date User Distance Calories
1614944833 1 100 32
1614944232 2 100 43
1624944831 1 150 23
1615944832 3 250 63
1614644836 1 500 234
1614954835 2 100 55
1614344834 3 100 34
1614964831 1 260 23
1614944238 1 200 44
user_subdomain Data:
User sub_domain
1 3
2 3
3 3
4 2
Subdomain data:
subdomain name
3 test1
4 test2
I would like to get sum value of distance,calories,count of records once they user reached sum of distance >= 1000.we should not count remaining records if user crossed 1000 distance.( if user crossed 1000,then 1000 else max distance value).
Expected Output:
Date record_count Distance Calories
1614964831 4 1000 312
1614954835 2 200 98
1614344834 3 350 97
So This result shows each users total effort they used to reach distance 1000 by record_count,then if they reached 1000 above then calculated as 1000,else max reached distance value,then total sum of that calories till 1000 cumulative sum reached.This is the output i need to retrieve.I tried with below query,but not works
Can anyone suggest with cumulative sum inner join method or any other solution for this?

Since MySQL 8.0 you can use window functions in next way:
with cumulative as (
-- calculate cumulative Distance & Calories
select
User,
Distance,
Calories,
sum(Distance) over (partition by User order by Date) SumDistance,
sum(Calories) over (partition by User order by Date) SumCalories
from Workout
order by User, Date
) select
User, max(SumDistance), max(SumCalories)
from cumulative
where SumDistance - Distance < 1000 -- filter
group by User;
MySQL window functions

Related

how can I write a query in mySQL which shows the average trips in a day?

I have a list of IDs and the detail of the trips they've taken. I want to see how many trips each ID takes in a day on average but I don't know how to write this query. The data I have in my table is something like this:
ID
Ride_id
Date
1
123
2022-3-4
1
124
2022-3-4
1
111
2021-2-8
2
584
2019-4-18
2
256
2019-4-18
2
805
2020-5-8
2
127
2020-5-8
2
457
2020-5-8
3
100
2021-4-7
3
101
2021-4-7
3
202
2021-5-17
3
741
2021-5-17
So basically, the average rides ID=1 takes is 1.5 and the average rides ID=2 takes is 2.5 and so on. I need a query to calculate and show the result like this:
ID
Average_of_daily_trips
1
1.5
2
2.5
3
2
My current query uses only one condition: WHERE ID in ()
First count the trips on each day for each id, then make the average over those counts.
select id, avg(trips)
from (select id, count(*) as trips
from trips
-- where id in(1,2,3)
group by id, date) t
group by id
If you need to, you can uncomment the where clause in the subquery to filter for particular ids ...

MySQL Select records exceeding the cumulative total

Given I have following table
Id
FileSizeMB
1
100
2
100
3
100
4
100
5
100
6
100
I want to select oldest records exceeding a cumulative value, in this case say 500.
So something like this
Id
Cumulative_FileSizeMB
6
100
5
200
4
300
3
400
2
500
1
600
I want to select only records with id 2 and 1 as they are >= 500.
Goal is to delete them.
Thanks
For anyone with same problem.
I have reached this solution using Mysql window functions,
and also there is no need to declare a variable for cumulative total
SELECT * from (
SELECT
id,
FileSizeMB,
SUM(FileSizeMB) OVER (ORDER BY id DESC) AS TotalFileSizeMB
FROM table
) as t1
WHERE TotalFileSizeMB > 500

How to get cumulative total for previous month and upto this month?

ID pcID contractor approver claimed
-------------------------------------------
1 1 one 1000 900
2 1 two 200 100
3 1 three 1000 1000
4 1 six 100 11
5 2 six 100 22
6 3 six 120 1
7 4 three 102 10
From the above table, I need to get cumulative amount for upto this month and previous month of approver and claimed and also current month approver, claimed amount based on the contractor. Like below table.
ID contractor approver claimed uptothisMTApprover uptothisMTClaimed previousMTApprover previousMTClaimed
-----------------------------------------------------------------------------------------------------------------
1 one 1000 900 1000 900 0 0
2 two 200 100 200 100 0 0
3 three 102 10 1102 1010 1000 1000
4 six 120 1 320 34 200 33
Thanks in advance..
You seem to want the latest row per contractor, as defined by pcID, and a cumulative sum of all previous months.
You can use window functions:
select contractor, approver, claimed,
total_approver as uptothisMTApprover,
total_claimed as uptothisMTClaimed,
total_approver - approver as previousMTApprover,
total_claimed - claimed as previousMTClaimed
from (
select t.*,
row_number() over(partition by contractor order by pcID desc) rn,
sum(approver) over(partition by contractor) total_approver,
sum(claimed) over(partition by contractor) total_claimed
from mytable t
) t
where rn = 1

Average with partial data in SQL

I have data as below, which is partial and few rows are missing. I need an average with data considering the previous available value. Do we have any function available for such an average in sql? 
Needed average: 220 
Available data for 10 days:
1st day: 100
4th day: 200
7th day: 300
10th day: 400
Putting the same in a table format:
Rows Date Partial Continuous(needed)
1 01-Aug-18 100 100
2 100
3 100
4 04-Aug-18 200 200
5 200
6 200
7 07-Aug-18 300 300
8 300
9 300
10 10-Aug-18 400 400
-----------------------------------
Average 250 220
-----------------------------------
I am looking at something like select avg(partial*(nextdate-date))/(lastdate-firstdate) from mytable;
Use a user-defined variable to fill in the missing values.
SELECT AVG(normal)
FROM (SELECT IFNULL(continuous, #prev) AS normal, #prev := IF(continuous IS NULL, #prev, continuous)
FROM (SELECT continuous
FROM yourTable
ORDER BY id) AS x
CROSS JOIN (SELECT #prev := NULL) AS y
) as z
What about AVG()?
> SELECT AVG(Normal) FROM table WHERE something;

SQL - Select All rows with Value X when a Row has Value Y

I am trying to get data from a row, then look up all rows with the data from that row.
My Table is like this:
Invoice Desc Item_Code Units Price Amount
1000 PHASE A 45 10 20 200
1000 BOLTS 16 45 1 45
1000 Jerry 10 1 100 100
1001 PHASE B 19 10 5 50
I want to return all rows with whatever is in Invoice when Desc is LIKE PHASE A.
I know enough to write:
SELECT
Invoice, Desc, Item_Code, Units, Price, Amount
FROM tbl
WHERE
Desc LIKE '%PHASE A%'
This will only return the row containing PHASE A - I want every row of PHASE A as below:
1000 PHASE A 45 10 20 200
1000 BOLTS 16 45 1 45
1000 Jerry 10 1 100 100
I feel like that should be in a IN statement, or I need to append an IN statement, but don't know where it should go.
I feel like that should be in a IN statement, or I need to append an
IN statement, but don't know where it should go.
Here
SELECT Invoice,
Desc,
Item_Code,
Units,
Price,
Amount
FROM tbl
WHERE Invoice IN (SELECT Invoice
FROM tbl
WHERE Desc LIKE '%PHASE A%')