MySQL select DATETIME similar up to the minute - mysql

I have to comapre the results relative to the same time between two tables, but the time stamps differs of some second because of how they were recorded.
I would like to obtain a result like in Example 1 but I get only the values with the asterisk, as in Example 2.
What is the best way to remove the secods from the comparison, or to select the value corresponding to the closest DATETIME value?
Currently I'm using this query:
SELECT Table1.TimeSTamp1, Table1.Param1, Table2.TimeStamp2, Table2.Param2
FROM Table1, Table2
WHERE ... conditions for the other parameters of Table1 and Table2...
AND Table1.TimeSTamp1 = Table2.TimeStamp2
Any suggestion on the best practice is warmly welcomed.
Example 1
TimeStamp1 ¦ Param1 ¦ TimeStamp2 ¦ Param2
2011-01-01 00:00:35 ¦ 1 ¦ 2011-01-01 00:00:35 ¦ a *
2011-01-01 00:01:35 ¦ 2 ¦ 2011-01-01 00:01:35 ¦ b
2011-01-01 00:02:37 ¦ 3 ¦ 2011-01-01 00:02:35 ¦ c
2011-01-01 00:03:31 ¦ 4 ¦ 2011-01-01 00:03:35 ¦ d
2011-01-01 00:04:32 ¦ 5 ¦ 2011-01-01 00:04:35 ¦ e
2011-01-01 00:05:38 ¦ 6 ¦ 2011-01-01 00:05:35 ¦ f
2011-01-01 00:06:36 ¦ 7 ¦ 2011-01-01 00:06:36 ¦ g *
2011-01-01 00:07:32 ¦ 8 ¦ 2011-01-01 00:07:35 ¦ h
2011-01-01 00:08:33 ¦ 9 ¦ 2011-01-01 00:08:35 ¦ i
2011-01-01 00:09:33 ¦ 10 ¦ 2011-01-01 00:09:33 ¦ l *
2011-01-01 00:10:35 ¦ 11 ¦ 2011-01-01 00:10:35 ¦ m *
2011-01-01 00:11:29 ¦ 12 ¦ 2011-01-01 00:11:31 ¦ n
lll
Example 2
TimeStamp1 ¦ Param1 ¦ TimeStamp2 ¦ Param2
2011-01-01 00:00:35 ¦ 1 ¦ 2011-01-01 00:00:35 ¦ a
2011-01-01 00:06:36 ¦ 7 ¦ 2011-01-01 00:06:36 ¦ g
2011-01-01 00:09:33 ¦ 10 ¦ 2011-01-01 00:09:33 ¦ l
2011-01-01 00:10:35 ¦ 11 ¦ 2011-01-01 00:10:35 ¦ m

This MySql expression will give you back DATETIME values with the seconds zeroed out.
CONVERT(DATE_FORMAT(table.column,'%Y-%m-%d-%H:%i:00'),DATETIME)
Take a look at this. https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format . So you might end up with a query like this:
SELECT Table1.TimeSTamp1, Table1.Param1, Table2.TimeStamp2, Table2.Param2
FROM Table1
JOIN Table2 ON CONVERT(DATE_FORMAT(Table1.TimeStamp1,'%Y-%m-%d-%H:%i:00'),DATETIME)
= CONVERT(DATE_FORMAT(Table2.TimeStamp2,'%Y-%m-%d-%H:%i:00'),DATETIME)
WHERE ... conditions for the other parameters of Table1 and Table2...
But, be careful. Autogenerated timestamps are kind of like floating point numbers; when two of them turn up equal to each other it's just luck. Truncating your timestamps to the minute may be OK, but you may also be better off subtracting one timestamp from another, and comparing the differences (or the absolute values of the differences).
Also, this join is going to be slow because it has to run the second-truncating function on every value, so it can't use any indexes.
You can subtract one timestamp from another with TIMESTAMPDIFF(). But be careful. This function only works correctly at the level of seconds for timestamps within a few days of each other; it overflows gracelessly (as I discovered with great pain).
You could try truncating the timestamps to minutes at the time you insert them. That would let you index them.

WHERE ...
AND ABS(UNIX_TIMESTAMP(TimeStamp1) - UNIX_TIMESTAMP(TimeStamp2)) < :threshold:
where threshold is the number of seconds after which you no longer want a match (e.g. 60 for 1 minute).

You could use TIMESTAMPDIFF to compute the difference in datetimes in seconds:
SELECT t1.TimeStamp1, t1.Param1, t2.TimeStamp2, t2.Param2
FROM Table1 t1
LEFT JOIN Table2 t2
ON ABS(TIMESTAMPDIFF(SECOND,t1.TimeStamp1,t2.TimeStamp2))<=4
WHERE ...
Noting Ollie Jones warning, I've tested TIMESTAMPDIFF on MySQL version 5.1.58 and found no overflow with timestamps differing by up to at least 10000 years. So maybe this problem has been fixed.

Related

MySql - build a view from 2 table with some calculations

I try to put together i bookingsystem and this part is left to understand. Can this be done with a CASE statement or how should i think?
I am a beginner and like short/easy code.
How do i get it from here...
date_source_table
---id---+-----date------+---times---+---
1 2020-01-02 3
2 2020-01-03 2
3 2020-01-04 3
time_source_table
---id---+----time------
1 09:00
2 09:30
3 10:00
date_time_result_view
---id---+-----date------+---time---+---
1 2020-01-02 09:00
2 2020-01-02 09:30
3 2020-01-02 10:00
4 2020-01-03 09:00
5 2020-01-03 09:30
6 2020-01-04 09:00
7 2020-01-04 09:30
8 2020-01-04 10:00
Best regards
/Svante
In MySQL 8+ You can use the row_number() window function to number the records in time_source_table. You can then join them to date_source_table on these numbers being less than or equal to date_source_table.times. You can also use row_number() to get the "IDs" for the output, if theses should in fact be just numbers from 1 to n.
SELECT row_number() OVER (ORDER BY dso.date,
tso.time) id,
dso.date,
tso.time
FROM date_source_table dso
INNER JOIN (SELECT tsi.time,
row_number() OVER (ORDER BY tsi.time) rn
FROM time_source_table tsi) tso
ON tso.rn <= dso.times;
If time_source_table.id is guaranteed to be in order of time and has no gaps you can also use that to join on. But if that column is just an AUTO_INCREMENT these guarantees aren't given. That may produce unwanted results all of a sudden. So use that with great care, if you must.

Formatting only First Row of table

I have an MS Access continuous form on onload event i am getting MyTable Record, upto here its fine. But i want to change the color of only first row
MyTable
Id ¦ Name ¦ Months ¦ Years
------------------
1 ¦ Ali ¦ 01 ¦ 2020
2 ¦ Umar ¦ 02 ¦ 2020
3 ¦ Abid ¦ 03 ¦ 2019
4 ¦ Sana ¦ 04 ¦ 2020
I used this code
Dim tblCount, Countr as Integer
tblCount = Dcount("Years", "MyTable")
For Countr = 1 to tbleCount
If countr = 1 Then
Me.Years.ForeColor = vbred
Else
Me.Years.ForeColor = vbblack
End If
Next Countr
When countr = 1 it shows all Years Column Red and when Countr > 1 Years Column becomes black
But i want only first row Years Red rest all rows Black
I really thankful to you plzz help me

SELECT with except several rows after current row by condition related with data in current row

Help me with query. I need somehow group row but i dont know.
We have table with data of clients calls and this query need for statistic.
Condition: several calls from one person in some date range in one item.
table:
id id_person created_date
1 1 2019-01-01 10:10:10
2 1 2019-01-02 10:10:10
3 1 2019-01-02 10:15:10
4 1 2019-01-05 10:20:10
5 2 2019-01-01 10:10:10
6 2 2019-01-02 10:10:10
7 3 2019-01-02 10:15:10
For e.g. we set gap param in 3 days
result of query:
1 1 2019-01-01 10:10:10
4 1 2019-01-05 10:20:10
5 2 2019-01-01 10:10:10
7 3 2019-01-02 10:15:10
For e.g. we set gap param in 1 day
result of query:
1 1 2019-01-01 10:10:10
3 1 2019-01-02 10:15:10
4 1 2019-01-05 10:20:10
5 2 2019-01-01 10:10:10
7 3 2019-01-02 10:15:10
Need group by person_id and excepting rows that include in row.created_date+gap
Your question has been asked before:
This solution should solve your issue and you can apply whichever gap parameter you want: Link
SELECT
id_person,
created_date,
DATEADD(DAY, NoGroup*3, '1999-01-01') AS [Gap Start],
DATEADD(DAY, NoGroup*3+2, '1999-01-01') AS [Gap End],
SUM(DPT)
FROM
(
SELECT
id_person,
created_date,
DATEDIFF(DAY, '1999-01-01', created_date) AS NoDays,
DATEDIFF(DAY, '1999-01-01', created_date)/3 AS NoGroup,
DPT
FROM your_table
) subquery
GROUP BY
id_person,
created_date;

Table data pass into stored procedure as param and insert into another table in mysql

I have this table and I need to pass each row value into a stored procedure and then it will return the list of dates for each row between start_date and end_date.
The procedure only returns two columns interval_start, interval_end but I'm trying to show the ID column from table A with the list of dates. After that, the output will insert into another table only once for each ID.
Table A:
ID start_date end_date
1 2016-01-01 2020-12-31
2 2017-01-01 2020-12-31
3 2018-01-01 2020-12-31
4 2019-01-01 2020-12-31
5 2020-01-01 2020-12-31
Stored procedure:
call make_intervals('2016-01-01','2020-12-31')
This procedure return:
interval_start interval_end
2016-01-01 2016-12-31
2017-01-01 2017-12-31
2018-01-01 2018-12-31
2019-01-01 2019-12-31
2020-01-01 2020-12-31
And I want to get this return as below and then insert into another table:
(sample)
aid interval_start interval_end
1 2016-01-01 2016-12-31
1 2017-01-01 2017-12-31
1 2018-01-01 2018-12-31
1 2019-01-01 2019-12-31
1 2020-01-01 2020-12-31
2 2016-01-01 2016-12-31
2 2017-01-01 2017-12-31
2 2018-01-01 2018-12-31
3 2019-01-01 2019-12-31
3 2020-01-01 2020-12-31
put this value into table B:
aid (int),
interval_start (date),
interval_end (date)
If any on of id insert once then this will not insert again.
Please help me to get this done.

multiple subquery result into main query, select in select

OK have 2 tables
user_id login_history
1 2011-01-01
1 2011-01-02
1 2011-03-05
1 2011-04-05
1 2011-06-07
2 2011-01-01
2 2011-01-02
3 2011-03-05
3 2011-04-05
3 2011-06-07
user_id user_details
1 Jack
2 Jeff
3 Irin
What kind of query can I use to get a result like
1. Jack 2011-01-01 2011-01-02 2011-03-05
2. Jeff 2011-01-01 2011-01-02
3. Irin 2011-03-05 2011-04-05 2011-06-07
Basically I want latest 3 records from table one and be joint with table 2
The query I used will get me a list of below, which is vertical records
Jack ,2011-01-01
Jack ,2011-01-02
Jack ,2011-03-05
Jeff ,2011-01-01
Jeff ,2011-01-02
Irin ,2011-03-05
Irin ,2011-04-05
Irin ,2011-06-07
Please help
select t2.user_details,
substring_index(group_concat(login_history order by login_history separator ' '),' ',3) as recents
from table_2 as t2
left join table_1 as t1
on t1.user_id = t2.user_id
group by t2.user_id
in your example you list first three records, not the last three. By the way you would have just to add desc to the order clause within group_concat if you need it.