Interval dates from two rows MySQL - mysql

I have sample data of date in the following table on MySQL:
Start End Source
===== === ====
2017-01-01 2017-02-14 T
2017-02-17 2017-02-28 T
2017-03-10 2017-03-15 T
And I want the interval date from End date to Start date. For ex:
(2017-02-17) - 2017-02-14) = 3 days or (2017-03-10)-(2017-02-28) = 10 days
Any ideas on where to start? A lot of the reading I've done just to get interval between two dates in one row. Thank you.

you can try to use DATEDIFF() function in mysql
your answer should be
SELECT DATEDIFF(Start,End) AS DiffDate from table
you can refer to this
https://www.w3schools.com/sql/func_datediff_mysql.asp

Try the query, and let me know if it worked or not?
SET #dateDiff=NULL;SET #dateDiff2='';
SELECT diff.dateDiffR AS dateDifference FROM (
SELECT aa.`end`,aa.`start`,IF(#dateDiff IS NULL,#dateDiff:=aa.end,0) AS try,
DATEDIFF(aa.`start`,#dateDiff) AS dateDiffR,
IF(#dateDiff!=#dateDiff2,#dateDiff2:=#dateDiff,0) AS try1,
IF(DATE(#dateDiff)!=DATE(aa.end),#dateDiff:=aa.end,NULL) AS assign
FROM test.`dateCheck` aa ) diff WHERE diff.dateDiffR>0

What you are trying to achieve is finding the time difference between two consecutive rows in the same table.
You can do it that way:
SELECT t1.ID, t1.Start, t1.End,
datediff(max(t2.End ), t1.Start) as minutes
FROM t as t1 LETF JOIN t as t2 on t1.ID = t2.ID
and t2.End < t1.Start
GROUP BY t1.ID, t1.Start, t1.End

I think he wants to get the difference between enddate from row 1 and startdate from row 2, and so on.
You have another identifier ? So i think you maybe need a "LEFT JOIN" or a subquery to handle this.
SELECT a.id, a.start, a.end, b.start, b.end, b.start - a.end AS `DIFF`
FROM table1 a
INNER JOIN table1 b ON b.id = a.id -1
So you have two results in one row and you can use diff and intervall as you do for one line .
I hope this idea helps you in the right direction

you should simply use join to calculate those date
select concat(datediff(n1.start,n2.end),' ',repeat('days',1)) as days
from table_name n1
join table_name n2
on n2.end < n1.start;
see here demo
if you don't need repeat "days" than simple use this query
select datediff(n1.start,n2.end)
from your_table n1
join your_table n2
on n2.end < n1.start;

Related

How to select only entries that didn't repeat before a specific date?

My issue is that I'm stuck on making a select query where I need to select only items from latest 24 hours, that don't repeat themselves on entries before those 24 hours.
Here is a table:
name
date
Mark
2021-05-27
Jake
2021-05-27
Anthony
2021-05-27
Anthony
2021-05-26
Expected output:
name
Mark
Jake
Missing element: query
Help will be appreciated.
Edit: I know that's unprecise. The real table I'm using is with full datetime type. I'm going to test your answers today and then give response.
'24 hours' is unprecise, as you do not know which dates of yesterday are actually in range of the past 24 hours. If you are ok only with today's entries only (which are less), then the following would work:
SELECT name FROM demoTable GROUP BY name HAVING MIN(date) = CURRENT_DATE;
If you actually have date and time available, then you can have:
SELECT name FROM demoTable
GROUP BY name HAVING MIN(datetime) > DATEADD(day, -1, CURRENT_TIMESTAMP);
Depending on SQL dialect, DATEADD(...) might not be available, with e. g. SQLite you'd replace it by DATETIME('now', '-1 day').
Use the below query to get the last 24 data without duplicate name
select name from tabl1 where date>getdate()-1 group by name having count(name)>0
Here getdate()-1 will give the last 1 day difference i.e. 24hr
SELECT DISTINCT t1.name
FROM tablename t1
WHERE t1.`date` = CURRENT_DATE
AND NOT EXISTS ( SELECT NULL
FROM tablename t2
WHERE t1.name = t2.name
AND t2.`date` < CURRENT_DATE );

How to calculate time difference between current and previous row in MySQL

I have mysql table t1 like this :
What i want to do is do calculations between all rows and save the value in new coloumn called diff
TICKETID| DATENEW | DIFF
16743 12:36:46 0
16744 12:51:25 15. minute
16745 12:57:25 6.5 minute
..........
.......
etc
i know there are similar questions ,but ive tried all of the solutions
posted here with no success,so how to solve this query ???
To get the time difference in minutes between the current and previous row, you can use timestampdiff on datenow and the previous time, which you can get via subquery:
select ticketid, datenew,
timestampdiff(minute,datenew,(select datenew from mytable t2
where t2.ticketid < t1.ticketid order by t2.ticketid desc limit 1)) as diff
from mytable t1
Update
Here's another way using a variable to store the previous datenew value that might be faster:
select ticketid, datenew, timestampdiff(minute,datenew,prevdatenew)
from (
select ticketid, datenew, #prevDateNew as prevdatenew,
#prevDateNew := datenew
from mytable order by ticketid
) t1
select
t1.*
,coalesce(timestampdiff(MINUTE,t2.dt,t1.dt),0) as tdiff
from t t1 left join t t2
on t1.id = t2.id+1
order by t1.id
As you are only looking for a difference between the current row and the next, you can join on the next row and calculate the time difference in minutes.
Note: This assumes there are no missing id's in the table. You might have to change the join condition if there were missing id's.
SQL Fiddle: http://www.sqlfiddle.com/#!9/4dcae/15

MYSQL get latest job number

I have this table:
TableNumber(Int 0 to 25)|Name(varchar 100)|Project(varchar 15)|StartDate(Datetime)
1 |David |P1 |'2015-02-06 08:00:00'
2 |Sebastien |P2 |'2015-02-06 08:00:00'
1 |David |P4 |'2015-02-06 12:00:00'
2 |Sebastien |P3 |'2015-02-07 08:00:00'
And I am looking to get the latest job for each person on a set day.
I would like to have:
TableNumber(Int 0 to 25)|Name(varchar 100)|Project(varchar 15)|StartDate(Datetime)
2 |Sebastien |P2 |'2015-02-06 08:00:00'
1 |David |P4 |'2015-02-06 12:00:00'
So I want to exclude P3 since its not '2015-02-06' and I want to exclude P1 cause its not the latest job for David (its P4).
Please consider that NOW() returns '2015-02-06 15:00:00' in the following exemples.
Here is what I tried:
SELECT * FROM MyTable WHERE DATEDIFF(startdate, NOW()) = 0 ORDER BY tablenum DESC;
But this only excluded P3
So I tried this instead:
SELECT * FROM MyTable AS p WHERE DATEDIFF(p.startdate, NOW()) = 0 AND TIMEDIFF(p.startdate, NOW()) = (SELECT MAX(TIMEDIFF(p2.startdate, NOW())) FROM MyTable AS p2 WHERE p2.startdate = p.startdate) ORDER BY tablenum DESC;
But Its still doesn't exclude P1.
Anyone know how I could achieve this? BTW startdate will always be a round hour (08:00:00 or 12:00:00 or 22:00:00...)
UPDATE
Yeah since it wasn't very clear what I wanted I will clarify here:
I need to know the last project worked on by every person.
so in my table I need to know that Sebastien work on P2 on table number 2 and that David work on P4 on table number 1. I don't want P1 because its not the last project that David worked on (by last project I also include the project he is working on right now). I also want to rule out everything in the future so P3 (who is tomorrow) must not display.
The following query will provide you with the date/time of the earliest job for a given name on a given day. In the following example I assumed you want the earliest jobs of each user on 2015-02-06.
SELECT Name, min(StartDate)
FROM MyTable
WHERE StartDate >= '2015-02-06'
AND StartDate < '2015-02-07'
GROUP BY Name
Using the above query, you can trivially get the final solution:
SELECT t1.project, t2.name, t2.StartDate
FROM MyTable t1 INNER JOIN
(SELECT Name, min(StartDate)
FROM MyTable
WHERE StartDate >= '2015-02-06'
AND StartDate < '2015-02-07'
GROUP BY Name) t2 ON t1.Name = t2.Name AND t1.StartDate = t2.StartDate

SELECT * FROM table while condition=true?

i want to select something from table while one condition is true,
SELECT * FROM (SELECT * FROM`table1` `t1` ORDER BY t1.date) `t2` WHILE t2.id!=5
when while condition comes to false it stop selecting next rows.
Please help me, I have already search a lot and many similars in stackoverflow but I can't get it.
please don't tell me about where , i want solution in sql not in php or anything other
OK the real problem is here
SELECT *,(SELECT SUM(t2.amount) FROM (select * from transaction as t1 order by t1.date) `t2`) as total_per_transition FROM transaction
here i want to calculate total balance on each transaction
First find the first date where the condition fails, so where id=5:
SELECT date
FROM table1
WHERE id = 5
ORDER BY date
LIMIT 1
Then make the above a derived table (we call it lim) and join it to the original table to get all rows with previous dates: t.date < lim.date
SELECT t.*
FROM table1 AS t
JOIN
( SELECT date
FROM table1
WHERE id = 5
ORDER BY date
LIMIT 1
) AS lim
ON t.date < COALESCE(lim.date, '9999-12-31') ;
The COALESCE() is for the case when there are no rows at all with id=5 - and in that case we want all rows from the table.

How to select the most recent set of dated records from a mysql table

I am storing the response to various rpc calls in a mysql table with the following fields:
Table: rpc_responses
timestamp (date)
method (varchar)
id (varchar)
response (mediumtext)
PRIMARY KEY(timestamp,method,id)
What is the best method of selecting the most recent responses for all existing combinations of method and id?
For each date there can only be one response for a given method/id.
Not all call combinations are necessarily present for a given date.
There are dozens of methods, thousands of ids and at least 365 different dates
Sample data:
timestamp method id response
2009-01-10 getThud 16 "....."
2009-01-10 getFoo 12 "....."
2009-01-10 getBar 12 "....."
2009-01-11 getFoo 12 "....."
2009-01-11 getBar 16 "....."
Desired result:
2009-01-10 getThud 16 "....."
2009-01-10 getBar 12 "....."
2009-01-11 getFoo 12 "....."
2009-01-11 getBar 16 "....."
(I don't think this is the same question - it won't give me the most recent response)
This solution was updated recently.
Comments below may be outdated
This can query may perform well, because there are no joins.
SELECT * FROM (
SELECT *,if(#last_method=method,0,1) as new_method_group,#last_method:=method
FROM rpc_responses
ORDER BY method,timestamp DESC
) as t1
WHERE new_method_group=1;
Given that you want one resulting row per method this solution should work, using mysql variables to avoid a JOIN.
FYI, PostgreSQL has a way of doing this built into the language:
SELECT DISTINCT ON (method) timestamp, method, id, response
FROM rpc_responses
WHERE 1 # some where clause here
ORDER BY method, timestamp DESC
Self answered, but I'm not sure that it will be an efficient enough solution as the table grows:
SELECT timestamp,method,id,response FROM rpc_responses
INNER JOIN
(SELECT max(timestamp) as timestamp,method,id FROM rpc_responses GROUP BY method,id) latest
USING (timestamp,method,id);
Try this...
SELECT o1.id, o1.timestamp, o1.method, o1.response
FROM rpc_responses o1
WHERE o1.timestamp = ( SELECT max(o2.timestamp)
FROM rpc_responses o2
WHERE o1.id = o2.id )
ORDER BY o1.timestamp, o1.method, o1.response
...it even works in Access!
i used this,worked for me
select max(timestamp),method,id from tables where 1 group by method,id order by timestamp desc
Subquery is very taxing when the data set becomes larger.
Try this:
SELECT t1.*
FROM rpc_responses AS t1
INNER JOIN rpc_responses AS t2
GROUP BY t1.method, t1.id, t1.timestamp
HAVING t1.timestamp=MAX(t2.timestamp)
ORDER BY t1.timestamp, t1.method, t1.response;
Checking the three main answers in some other use case shows that the most voted answer is also by far the fastest, swarm intelligence works here:
# Answer 1: https://stackoverflow.com/a/12625667/11154841
# 165ms
SELECT
COUNT(0)
FROM
(
SELECT
mtn.my_primary_key,
mtn.my_info_col,
IF(#last_my_primary_key = my_primary_key,
0,
1) AS new_my_primary_key_group,
#last_my_primary_key := my_primary_key
FROM
my_db_schema.my_table_name mtn
WHERE
mtn.date_time_col > now() - INTERVAL 1 MONTH
ORDER BY
my_primary_key,
mtn.date_time_col DESC
) AS t1
WHERE
new_my_primary_key_group = 1
AND t1.my_info_col = 'delete';
# Answer 2: https://stackoverflow.com/a/435709/11154841
# 757ms
SELECT
count(0)
FROM
my_db_schema.my_table_name mtn
JOIN
(
SELECT
my_primary_key,
max(date_time_col) AS date_time_col
FROM
my_db_schema.my_table_name mtn
WHERE
mtn.date_time_col > now() - INTERVAL 1 MONTH
GROUP BY
mtn.my_primary_key) latest
USING (my_primary_key,
date_time_col)
WHERE
mtn.my_info_col = 'delete';
# Answer 3: https://stackoverflow.com/a/3185644/11154841
# 1.310s
SELECT
count(0)
FROM
my_db_schema.my_table_name mtn
WHERE
mtn.date_time_col = (
SELECT
max(mtn2.date_time_col)
FROM
my_db_schema.my_table_name mtn2
WHERE
mtn2.my_primary_key = mtn.my_primary_key
AND mtn2.date_time_col > now() - INTERVAL 1 MONTH
)
AND mtn.date_time_col > now() - INTERVAL 1 MONTH
AND mtn.my_info_col = 'delete';
The concept of "most recent" is fairly vague. If you mean something like the 100 most recent rows then you can just add a TOP(100) to your SELECT clause.
If you mean the "most recent" based on a the most recent date then you can just do
SELECT timestamp,method,id,response
FROM rpc_responses
HAVING max(timestamp) = timestamp
...is more than one year later but i might help someone
To select all the queries starting from latest
SELECT *
FROM rpc_responses
ORDER BY timestamp DESC