MySQL: Compute difference of two timestamps in different table rows - mysql

I keep on looking around StackOverflow for a similar question but it seems that I can't find one. I would like to know the difference between timestamps in different rows grouped by employee ID.
Time Logs table:
id timestamp log_type
1 2019-06-19 12:34:50 log_in
2 2019-06-19 13:12:46 start_break
3 2019-06-19 13:13:56 end_break
4 2019-06-19 17:23:40 start_break
5 2019-06-19 17:44:36 end_break
6 2019-06-19 19:00:04 start_break
7 2019-06-19 19:03:17 end_break
8 2019-06-19 20:05:54 log_out
What I'm trying to accomplish is to calculate all duration of breaks. In this case, 1st break (id #2 and #3) is 1 minute and 10 seconds, 2nd break (id #4 and #5) is 20 minutes and 56 seconds, 3rd break (id #6 and #7) is 3 minutes and 13 seconds thus with the total of 25 minutes and 19 seconds.
Thanks for helping out! Much appreciated.

You can try below -
DEMO
select SEC_TO_TIME(sum(diff)) as result from
(
select
timestampdiff(second,min(case when log_tpe='start_break' then timestamps end) ,
min(case when log_tpe='end_break' then timestamps end)) as diff
from t
group by date(timestamps),hour(timestamps)
)A
OUTPUT:
result
00:25:19

Related

Sort values in two column and insert order position into another column in mysql

I have a database about sports event that contains:
*User ID
*Amount of Points that the user got on that event
*Time (HH:MM:SS) that took the user to complete track.
How can I first sort them by no. of points, then if two users have same amount of points, by time (shorter is better); and then insert the places to rows?
I have database like that:
ID No. of Points Time Place
------------------------------------
1 15 00:56:00
2 13 00:55:15
3 17 01:00:00
4 17 00:57:00
5 19 00:52:15
I need to have it with places:
ID No. of Points Time Place
------------------------------------
1 15 00:56:00 4
2 13 00:55:15 5
3 17 01:00:00 3
4 17 00:57:00 2
5 19 00:52:15 1
I hope, you understand that. Sorry for bad English.
Best regards,
You can do this with update statement as follows.
SET #placeValue:=0;
UPDATE [Table Name] SET Place=#placeValue:=#placeValue+1 ORDER BY
[Amount of Points] DESC,Time ASC

Selecting id with difference betwen dates in same row being less than 30 days, but without new date in different row

I have a table like this
id plan_id cancel_date paid_date
9 2 2015-08-05 2014-09-13
10 2 2015-09-08 2015-09-03
10 3 NULL 2015-09-10
11 3 NULL 2015-09-13
14 3 2015-09-28 2015-09-14
And I would like to select ids where there is a less than 30 days difference between cancel_date and paid_date (for a given plan), and they didn't acquired a new plan in less than 30 days.
In this case, this would mean returning id 14 only.
Update:
Whenever a user buy a new plan, we insert it to the table, with a different paid_date (paid_date is the date that the plan was acquired the first time).

Select rows with the lowest M values, out of N values

I have a table that's structured like so:
id value hour
1 4 176475
2 2 176475
3 3 176475
4 2 176475
1 2 184563
2 1 184563
3 4 184563
4 3 184563
... ... ...
1 2 N
2 3 N
3 1 N
4 4 N
The key property is that the data is split into hours which are in ascending order. The 'hours' are timestamps truncated to enforce 24 buckets per day. I want to do several things:
Pull all of the rows for the first hour
Sum values for each ID over 3 hours, 8 hours...N hours.
Is there a simple way to do this? I am aware that I could use NTILE to label the data but that's a very expensive operation in Spark.
EDIT:
Expected Result for aggregating hours 1-3:
id value
1 9
2 7
3 10
4 8
The values are made up, but the idea is to sum the values of the IDs in each of the 3 hours, so that I have one value per ID, instead of three.
This is the query you're looking for:
SELECT id, SUM(value) as `value`
FROM yourTableHere
WHERE hour between (NOW() - INTERVAL X HOUR) AND NOW()
GROUP BY id, hour
Breaking the query down.
Select the ID and count the value from yourTable.
Where hour is between X hours ago and now.
Group the results by id and hour between the given timestamps.
Replace X with 1/3/8 or more for the hours you wish.

Finding Two Consecutive Dates

Hi I have a table "EMP_LEAVE" with some records as below
Employee | Leave_Start_Date | Leave_End_Date
1 22-09-2014 26-09-2014
1 29-09-2014 03-10-2014
1 15-12-2014 19-12-2014
1 22-12-2014 24-12-2014
2 07-01-2014 10-01-2014
2 13-01-2014 17-01-2014
2 20-01-2014 24-01-2014
3 10-02-2014 13-02-2014
3 17-02-2014 21-02-2014
I want to write a SQL query to find:
Employee who has taken leaves more than or equal to "Two Consecutive" weeks or I should say Two weeks in a row?
If Yes then whats there Leave_Start_Date and Leave_End_Date for those total leaves?
Any help or direction will be appreciated.
You can write some simple query as below.
select employee,
Leave_start_date,
Leave_end_date
from emp_leave
where datediff(Leave_start_date, Leave_end_date) >= 15
This query will give you the employees which have taken leave for more than 15 days.
Thanks,
Sarat

MySQL GROUP BY with multiple parameters hiding zeros

I've read similar questions here on stackoverflow, but the OP's table structure is never quite the same as mine, so the answer doesn't work for me. The posts I've read are only trying to GROUP BY one column as opposed to two. I'm using MySQL, latest stable release.
Here's my table "reference":
id formatID referenceTime
1 1 2011-6-12 12:40
2 2 2011-6-12 1:04
3 4 2011-6-12 1:03
4 2 2011-6-12 15:20
5 3 2011-6-12 9:30
6 3 2011-6-12 2:55
7 5 2011-6-12 13:15
8 1 2011-6-12 12:32
(etc)
I want to create a query that show how many of each type of format occurred by hour of day. The point of this is to see what is the busiest time of day. I am trying to write a query that will create output that I can use for some simple graph web apps (Highcharts.js). I want it to look like this:
Timeofday Subgroup Count
12AM 1 2
12AM 2 6
12AM 3 7
12AM 4 2
12AM 5 0
1AM 1 3
1AM 2 3
1AM 3 0
1AM 4 0
1AM 5 1
(etc)
I'm using this query:
SELECT date_format(referenceTime,'%I %p') AS timeofday,
reference.referenceFormatID AS subgroup,
count(*) AS count
FROM reference
GROUP BY timeofday,subgroup ASC
However, the output skips "rows" where the count equals zero and so ends up looking like this:
Timeofday Subgroup Count
12AM 1 2
12AM 2 6
1AM 3 7
1AM 4 2
1AM 5 1
3AM 1 3
6AM 2 3
7AM 3 1
7AM 4 1
9AM 5 1
(etc)
I need those zeros to be able to create a properly formatted data series for my app.
The LEFT JOIN method where you put all the times into a second table isn't working for me because I am grouping by two different columns. Apparently, the LEFT JOIN criteria is satisfied as long as each hour shows up somewhere in the output table, but I need each hour to appear for each format.
Any suggestions?
You have two options, either create a lookup table with the possible hours in it, or use strange query involving the dual table and union to get the values that you are looking for.
In the first case, you would have a table with maybe a single field for the moment, let's just call it hours and the field is timeofday.
In the hours timeofday, you would have the following data:
timeofday
12AM
1AM
2AM
....
Then your query is as simple as
SELECT hours.timeofday,
reference.referenceFormatID AS subgroup,
count(reference.referenceFormatID) AS count
FROM hours
LEFT JOIN reference on date_format(referenceTime,'%I %p') = hours.timeofday
GROUP BY hours.timeofday,subgroup ASC
EDIT
To get all combinations, you would also need a formats table with all the possible formatIDs as was mentioned by rfausak. You could also do this with a distinct, but let's just assume that you have this table, let's call it formats. Again, this table could have a single column.
Part 1 is to get all the combinations:
SELECT hours.timeofday,
formats.ID
from hours
join formats
This is a Cartesian join that would merge all possible hours and format IDs.
Now we add in the LEFT JOIN
SELECT hours.timeofday,
formats.ID,
count(reference.subgroup)
FROM hours
JOIN formats
LEFT JOIN reference on date_format(referenceTime,'%I %p') = hours.timeofday
AND reference.subgroup = formats.ID
GROUP BY hours.timeofday,formats.ID ASC
If you try to do it using a DUAL table look up, you can use a method similar to generate days from date range