Get difference between two records - mysql

I got a User-Information table where every 24 hours a new record is added for each user. This record contains a user_id, a value (a counter) and the creation date.
TBL_EXAMPLE
ID | user_id | cnt_val | record_date
--------------------------------------------
1 | 10 | 46 | 2019-02-05 12:14:35
2 | 21 | 12 | 2019-02-05 12:14:35
3 | 32 | 453 | 2019-02-05 12:14:35
4 | 10 | 23 | 2019-02-06 16:11:21
5 | 21 | 34 | 2019-02-06 16:11:21
6 | 32 | 480 | 2019-02-06 16:11:21
7 | 10 | 31 | 2019-02-07 11:34:25
8 | 21 | 44 | 2019-02-07 11:34:25
9 | 32 | 489 | 2019-02-07 11:34:25
...
Expected Result:
User 10 Counter: 46 .. 31 --> Difference: 15
User 21 Counter: 12 .. 44 --> Difference: 32
User 32 Counter: 453.. 489 --> Difference: 36
I want to make a list of each difference for each specific user from the oldest to the newest data record in the table dynamically.

you could use inner join twice on table_exeple and a subquery for min and max date
select distinct t1.user_id, t1.cnt_va - t2.cnt_val
from (
select user_id , min(date) min_date, max(date) max_date
from TTBL_EXAMPLE
group by user_id
) tmm
inner join TTBL_EXAMPLE t2 ON t2.date = tmm.max_date
and t2.user_id = tmm.user_id
inner join TBL_EXAMPLE t1 ON t1.date = tmm.min_date
and t1.user_id = tmm.user_id

Related

How to write an SQL query to calculate the average for three consecutive values?

I have a table like this
userID time NoOfVisits
1 2014 50
2 2015 60
3 2016 70
4 2017 80
5 2018 90
6 2019 100
I need to write a sql query which will print time and average of past 3 years NoOfVisits for a particular site.
output should be as
userID time NoOfVisits
1 2014 50.0000
2 2015 55.0000
3 2016 60.0000
4 2017 70.0000
5 2018 80.0000
6 2019 90.0000
Explanation :
For user Id 6 (80+90+100)/3=90.0000
Please help me to solve this problem.
You can use a cumulative average, available in MySQL 8+:
select t.*,
avg(visits) over (order by time rows between 2 preceding and current row) as avg_visits_3
from t;
Assuming there are no gaps between the years (like your sample data), you can self join the table and group by userid, time to get the average:
select
t.userid, t.time, avg(tt.noofvisits) NoOfVisits
from tablename t inner join tablename tt
on tt.time between t.time - 2 and t.time
group by t.userid, t.time
See the demo.
Results:
| userid | time | NoOfVisits |
| ------ | ---- | ---------- |
| 1 | 2014 | 50 |
| 2 | 2015 | 55 |
| 3 | 2016 | 60 |
| 4 | 2017 | 70 |
| 5 | 2018 | 80 |
| 6 | 2019 | 90 |

how to select the row where sum reach 1000?

id | amount
1 | 96
2 | 0.63
3 | 351.03
4 | 736
5 | 53
6 | 39
7 | 105
8 | 91
I want to get the row where sum(amount) reach 1000
please note only the row that trigger 1000
This query should do what (I think) you want:
select id, (select sum(amount)
from table1 t1
where t1.id <= table1.id) as total
from table1
having total >= 1000
limit 1
For your sample table, it gives
id total
4 1183.66

Match column name to data in MYSQL

I have data like in table.
Item | 7/7/15 | 7/8/15 | 7/9/15
1 | 23 | 24 | 25
2 | 26 | 74 | 96
and
I have table which has,
Item | Date | Number
1 | 7/9/15 | 56
1 | 7/7/15 | 75
1 | 7/8/15 | 63
I want to find sum of Number from 7/7/15 to 7/8/15 from table 1 and sum of the number from second table.
My table should look like
Item | StartDate | EndDate | no. | TotalNumber
item 7/7/15 7/8/15 7/9/15
1 23 24 25
2 26 74 96
item date number
1 7/9/15 56
1 7/7/15 75
1 7/8/15 63
.
SELECT
i1.Item,
'7/7/15' AS "StartDate",
'7/8/15' AS "EndDate",
(SELECT SUM(`7/7/15`)+SUM(`7/8/15`) FROM table1 WHERE item=i1.item) AS no,
(SELECT SUM(number) FROM table2 WHERE item=i1.item) "TotalNumber"
FROM
table2 i2
RIGHT OUTER JOIN table1 i1 on i1.item=i2.item;
item startdate enddate no TotalNumber
1 7/7/15 7/8/15 47 194
1 7/7/15 7/8/15 47 194
1 7/7/15 7/8/15 47 194
2 7/7/15 7/8/15 100
.
It's working..

I would like to find the difference of each row, from the first row As Alias

To clarify my Title
I would like to tabulate how far behind the leader, each successive finisher is from 1st place as shown in my table below.
Finish | Points | Points Behind
1 | 102 |
2 | 92 | 10
3 | 82 | 20
4 | 71 | 31
5 | 61 | 41
6 | 50 | 52
7 | 40 | 62
8 | 30 | 72
9 | 20 | 82
10 | 10 | 92
Select
snpc_stats.gamedetail.Finish,
snpc_stats.gamedetail.Points,
some code I don't know As 'Points Behind'
From
snpc_stats.gamedetail
Where
snpc_stats.gamedetail.GamesID = 113
You can get the points from first finish and do a cross join with rest of the table.
SQL Fiddle
select gd.Finish, gd.Points,
t.Points-gd.Points as PointsBehind
from gamedetail gd
cross join ( select max(Points) from gamedetail where Finish =1) t

Query to select intervals in day

I have table something like this (there's also "device_id" and "timestamp" columns)
day | interval | value
----------------------------
1 | 14 | 63 // start of a day
1 | 14 | 83
1 | 14 | 73
1 | 15 | 23
1 | 15 | 33
1 | 15 | 50
2 | 16 | 23 // start of a day
2 | 16 | 33
2 | 16 | 50
I want to select all intervals in a day. That is simple.
However, an interval can start a bit before a day flips, or end a bit past:
day | interval | value
----------------------------
7 | 14 | 63
7 | 14 | 83
8 | 14 | 73 // start of a day
8 | 15 | 23
8 | 15 | 33
8 | 15 | 50
8 | 16 | 23
8 | 16 | 33
9 | 16 | 50 // start of a day
Now I'd like to select all three intervals - or even better intervals that are mostly in that day.
SELECT ... WHERE day = 8
Gives me only parts of the start/end intervals (14, 16). That's useless, I need the complete intervals.
If there's no solution, I'll just do three queries, but there might be some SQL trick I'm not aware of?
It's MySQL, called from PHP.
More visually:
day 7 | day 8 | day 9
------------------+-------------------+---------------
###13### ###14### ###15### ###16### ###17###
... 63 83 73 23 33 50 23 33 50 ...
I want all values in day 8 -> intervals 14, 15, 16
I think you are looking for this:
SELECT * FROM intervals
WHERE interval IN (
SELECT DISTINCT interval FROM intervals WHERE day = 8)
This selects all interval data where at least one of the entries for that interval occurs in day 8. The subquery determines which unique intervals happen in the day, which is then used by the outer query to select their specifics.
SELECT DISTINCT y.*
FROM my_table x
JOIN my_table y
ON y.some_column = x.some_column
WHERE x.some_other_column = 8;