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
Related
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;
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.
I have a PHP program w/MySQL database which contains many records. Two columns of particular relevance are incidentnumber and date. These both move forward only. However, sometimes a user enters data which is out of sequence; eg:
Incident Date
1 Jan 1 2000
2 Jan 1 2010
3 Jan 1 2002
It appears that incident 2 was entered with the wrong date, it should be Jan 1 2001.
Is there any way to query for records where the date is out of sequence? Or do I have to iterate through all records tracking last date to find the error?
ADDED NOTE: The incidents are not sequential (they might go 1,3,6,123, etc). Nor are the dates sequential. And these are columns in the same table.
This command selects any records for which there exists in the same table a record with a lower Incident number but a higher Date.
SELECT * FROM TableName T1 WHERE EXISTS
(SELECT * FROM TableName T2
WHERE T2.Incident < T1.Incident AND T2.Date > T1.Date)
This slightly more complex command will find only records for which are out of order in "both directions", meaning they have an later dated record earlier in the file and an earlier dated record later in the file. This avoids the situation in which making a mistake in a very early record in the file will make all the subsequent records appear out of order. However, it will not catch a problem in the two records with the lowest or highest incident numbers.
SELECT * FROM TableName T1 WHERE EXISTS
(SELECT * FROM TableName T2
WHERE T2.Incident < T1.Incident AND T2.Date > T1.Date)
AND EXISTS
(SELECT * FROM TableName T2
WHERE T2.Incident > T1.Incident AND T2.Date < T1.Date)
Finally, as ruakh points out in the comments, the above query gives you ALL the out-of-order records. Although that is, technically, what you wanted it makes it difficult to find the "point of breakage" in the chain of dates. The following query will give you only the records where the chain gets messed up, does not require IncidentID to increase monotonically, and allows deletions of incidents.
SELECT * FROM TableName T1 WHERE
Date < (SELECT Date FROM TableName T2 WHERE T2.IncidentID =
(SELECT MAX(IncidentID) FROM TableName T3 WHERE T3.IncidentID < T1.IncidentID))
OR Date > (SELECT Date FROM TableName T2 WHERE T2.IncidentID =
(SELECT MAX(IncidentID) FROM TableName T3 WHERE T3.IncidentID > T1.IncidentID))
(Not tested, since I don't have a copy of MySQL handy).
select * from yourtable t1
inner join yourtable t2
on t1.incident=t2.incident-1
and t1.date>t2.date
This selects all of the ids where the date is greater than the next records date. That should tell you which ones are out of order.
SELECT Incident FROM table a
WHERE a.Date > (SELECT b.Date FROM table b WHERE b.Incident = (a.Incident + 1))
In case that the IncidentID column is always in a regular incremental sequence:
SELECT c.IncidentID AS cincID, p.IncidentID AS pincID,
c.Date AS cDate, p.Date AS pDate,
DATEDIFF(c.Date, p.Date)
FROM Incident c, Incident p
WHERE c.IncidentID = (p.IncidentID + 1)
AND datediff(c.Date, p.Date) < 1
I have a mysql database with vehicles records. I need a fast query that will return the newest records of those records that were updated within the last 4 minutes. For example vehicle "A" may be updated several times a minute so it will appear many times within the last 4min. Same with vehicle B C etc. I need only the most recent entries for each vehicle within a 4 min window. I have tried like this
SELECT *
FROM yourtable AS a
WHERE a.ts =
(SELECT MAX(ts)
FROM yourtable AS b
WHERE b.ts > NOW() - INTERVAL 5 MINUTE
AND b.name = a.name)
but it takes too long to produce results >10seconds.
You don't need the self-join.
select max(ts), name from Table1
where ts > NOW() - INTERVAL 5 MINUTE
group by name
To get all the rows for the latest updates and not only the name and timestamp:
SELECT t.*
FROM
TableX AS t
JOIN
( SELECT name
, MAX(ts) AS maxts
FROM TableX
WHERE ts > NOW() - INTERVAL 4 MINUTE
GROUP BY name
) AS grp
ON grp.name = t.name
AND grp.maxts = t.ts
You'll need at least an index on the timestamp column for this query.
I've searched around SO and can't seem to find a question with an answer that works fine for me. I have a table with almost 2 million rows in, and each row has a MySQL Date formatted field.
I'd like to work out (in seconds) how often a row was inserted, so work out the average difference between the dates of all the rows with a SQL query.
Any ideas?
-- EDIT --
Here's what my table looks like
id, name, date (datetime), age, gender
If you want to know how often (on average) a row was inserted, I don't think you need to calculate all the differences. You only need to sum up the differences between adjacent rows (adjacent based on the timestamp) and divide the result by the number of the summands.
The formula
((T1-T0) + (T2-T1) + … + (TN-TN-1)) / N
can obviously be simplified to merely
(TN-T0) / N
So, the query would be something like this:
SELECT TIMESTAMPDIFF(SECOND, MIN(date), MAX(date)) / (COUNT(*) - 1)
FROM atable
Make sure the number of rows is more than 1, or you'll get the Division By Zero error. Still, if you like, you can prevent the error with a simple trick:
SELECT
IFNULL(TIMESTAMPDIFF(SECOND, MIN(date), MAX(date)) / NULLIF(COUNT(*) - 1, 0), 0)
FROM atable
Now you can safely run the query against a table with a single row.
Give this a shot:
select AVG(theDelay) from (
select TIMESTAMPDIFF(SECOND,a.date, b.date) as theDelay
from myTable a
join myTable b on b.date = (select MIN(x.date)
from myTable x
where x.date > a.date)
) p
The inner query joins each row with the next row (by date) and returns the number of seconds between them. That query is then encapsulated and is queried for the average number of seconds.
EDIT: If your ID column is auto-incrementing and they are in date order, you can speed it up a bit by joining to the next ID row rather than the MIN next date.
select AVG(theDelay) from (
select TIMESTAMPDIFF(SECOND,a.date, b.date) as theDelay
from myTable a
join myTable b on b.date = (select MIN(x.id)
from myTable x
where x.id > a.id)
) p
EDIT2: As brilliantly commented by Mikael Eriksson, you may be able to just do:
select (TIMESTAMPDIFF(SECOND,(MAX(date),MIN(date)) / COUNT(*)) from myTable
There's a lot you can do with this to eliminate off-peak hours or big spans without a new record, using the join syntax in my first example.
Try this:
select avg(diff) as AverageSecondsBetweenDates
from (
select TIMESTAMPDIFF(SECOND, t1.MyDate, min(t2.MyDate)) as diff
from MyTable t1
inner join MyTable t2 on t2.MyDate > t1.MyDate
group by t1.MyDate
) a