how to get a list of rows that is between 17:30 till tomarrow 8:30.
--------------------------------------
| id | user_id | action | time |
--------------------------------------
| 1 | 25 | enter | 1512459905
| 2 | 19 | exit | 1512125105
| 3 | 31 | enter | 1514581905 |
--------------------------------------
mysql table have a time column with unix timestamp and i want get a list every day that between 17:30 till 8:30
SELECT TIME_TO_SEC(TIMEDIFF(FROM_UNIXTIME('time 1'), FROM_UNIXTIME('time 2')) AS 'time_diff_in_sec' FROM 'your_table';
This can help:
Mysql Get Time Diff
$dateStart=strtotime(date("Y-m-d 17:30:00"));
$dateEnd=strtotime(date("Y-m-d 20:30:00"));
This is how you can convert your date into unix timestamp in php.
Then in your query:
SELECT * FROM my_table WHERE time BETWEEN '$dateStart' AND '$dateEnd'
If you don't want to execute your script manually every day you can set up a cronjob to do it for you.
You can use the TIME() function to extract the time part of the datatime,
So you can do something like this:
select * FROM table t
where TIME(f.time) between '17:30:00' AND '18:30:00'
Related
In my MySql DB I have these fields:
id | email_id | interval | start_at | last_sent_at
--- | -------- | ---------- | ------------------- | -------------------
1 | 8293 | +6 months | 2017-06-14 16:59:54 | 2017-06-14 16:59:54
--- | -------- | ---------- | ------------------- | -------------------
2 | 8904 | (NULL) | 2017-05-14 12:32:45 | (NULL)
I am trying to create a dynamic way for users to set a schedule for an email job in laravel. The idea is to use laravel's commands scheduler to run a command that checks all scheduled emails and then runs them if they haven't been sent (whereNull(last_sent_at)) or if the last time they were sent was more than the current time minus 6 months or 12 months or what ever they select for that field.
I have tried several different queries to get this to work to no avail. In laravelized code I have tried the following...
$schedules = Schedule::selectRaw('schedules.schedulable_id, schedules.schedulable_type, UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(schedules.interval) as NowPlusInterval')
->whereNull('last_sent_at')
->orWhere('schedules.last_sent_at', '>=', 'NowPlusInterval')
->get();
and
$schedules = Schedule::whereNull('last_sent_at')
->orWhereRaw('schedules.last_sent_at >= NOW()-'.Carbon::parse('schedules.interval')->toDateTimeString())
->get();
and many many other variations. The second one is the simplest to me but because I am passing the db field to a php function it doesn't recognize that I am trying to get the value from the db field (not parse a string called 'schedules.interval'). Is there anyway write this field into a variable that Carbon can parse or is there a raw mysql query that I can run that will give me all the fields where last_sent_at is null and where now minus the interval listed is more than the last_sent_at.
I've racked my brain on this for hours. Any help is appreciated.
Try using mysql's DATE_SUB() and INTERVAL functions. Something to the effect of:
->whereRaw('last_sent_at >= SUB_DATE(NOW(), INTERVAL 6 MONTH)')
or perhaps this:
->whereNull('last_sent_at')
->orWhere(DB::raw('DATE(`schedules.last_sent_at`) >= DATE_SUB(NOW(), INTERVAL `schedules.interval`')))
->get();
This is the table:
+----+-----------+------------+----------+
| id | id_sensor | start_time | end_time |
+----+-----------+------------+----------+
| 1 | 12 | 21:15:00 | 02:45:00 |
| 2 | 7 | 00:00:00 | 23:15:00 |
| 3 | 5 | 04:30:00 | 16:30:00 |
+----+-----------+------------+----------+
I need to get record(s) where a specific time (e.g. 01:00:00) passed by PHP is between. start_time and end_time are TIME fields in UTC, I'm passing to the query hour via php, note, converted in php from user_timezone to UTC.
SELECT * FROM test WHERE TIME('01:00:00') BETWEEN start_time AND end_time;
Query returns only record id 2, not the 1. I need both, in this case (for id 1, end time ofcourse is next day).
Of course, if we looking for TIME('01:00:00'), we don't need the id 3.
Thank you.
I think this is the logic you want:
SELECT *
FROM test
WHERE (start_time < end_time AND TIME('01:00:00') BETWEEN start_time AND end_time) OR
(start_time > end_time AND TIME('01:00:00') NOT BETWEEN end_time AND start_time);
now() returns both, current time and date. You can also work with curtime(), which returns only the current time.
BTW, i think that working with SELECT * should be avoided (maybe you used it just for this example), it is IMHO always better to list the fields needed explicitly.
I want to compare the current row to the next to check if the third column of the current row is the same as to the next. If not, the current row index will adjust as the new current row and check again the next row. I want to do this in php. Can somebody help me.
UPDATED:
ID | Date | Time
------+-----------+-------
00091 | 2015-1-20 | 08:05
00091 | 2015-1-20 | 17:10
00099 | 2015-1-20 | 07:45
00099 | 2015-1-20 | 17:42
my expected outputs are:
ID | Date | Time
------+-----------+-------------
00091 | 2015-1-20 | 08:05 17:10
00099 | 2015-1-20 | 07:45 17:42
This looks like a terrible database design, so I would highly recommend changing it! Having duplicate IDs hurts me deeply.
But, here's a MySQL query that could get the result you are after:
SELECT `ID`, `Date`, CONCAT(MIN(`Time`), ' ', MAX(`Time`)) AS `Time`
FROM `test`
GROUP BY `ID`, `Date`;
I am trying to select data, when inserting the data it has an auto insert of the date when submitting. So when data is inserted it inserts the current date.
However, in my table I have week beginnings, so I am trying to select the data inside of that week:
mysql> select * from week;
+---------+------+------------+
| week_id | week | date |
+---------+------+------------+
| 1 | 1 | 2014-12-29 |
| 2 | 2 | 2015-01-05 |
| 3 | 3 | 2015-01-12 |
| 4 | 4 | 2015-01-19 |
| 5 | 5 | 2015-01-26 |
| 6 | 6 | 2015-02-02 |
| 7 | 7 | 2015-02-09 |
| 8 | 8 | 2015-02-16 |
| 9 | 9 | 2015-02-23 |
| 10 | 10 | 2015-03-02 |
| 11 | 11 | 2015-03-09 |
| 12 | 12 | 2015-03-16 |
| 13 | 13 | 2015-03-23 |
| 14 | 14 | 2015-03-30 |
| 15 | 15 | 2015-04-06 |
| 16 | 16 | 2015-04-13 |
| 17 | 17 | 2015-04-20 |
e.g.
select * from table where date='2015-04-06';
However the data will not be selected and presented because the inserted date was 2015-04-10. The only way to retrieve that data is by doing this:
select * from table where date='2015-04-10'; < when the data was inserted
So my question is, is it possible to select that data from that week beginning?
So if I select data from 2015-04-06 it should show data from the range of 2015-04-06 to 2015-04-12, is that possible?
Hopefully I have explained correctly, been a bit tricky to explain let alone try to implement. I can add any more info if needed.
NOTE: I am trying to use this inside of PHP so where the date is I would just use a variable, just thought I would say.
As the week will always end 6 days from the beginning you can use the between operator and the date_add function like this:
(for your specific example):
select *
from table
where date between '2015-04-06' and date_add('2015-04-06', interval 6 day)
And using a php variable:
select *
from table
where date between '$name_of_dt_var' and date_add('$name_of_dt_var', interval 6 day)
You could also compare the week of the date the data was entered with the weeks in the week table using WEEK() function.
Assuming that week is the same value as week(), the:
select t.*
from table t
where week = week('2015-04-10');
Even if the numbers do not match, then presumably you have some base date (such as 2015-01-01 and simple arithmetic would accomplish something very similar).
I have found that the most robust way to do this sort of week processing is to truncate each date in the table (in your example 2015-04-10) to the preceding Monday at midnight. That way you can compute the week of each item by assigning it to the first day of that week.
This little formula returns the preceding Monday given any DATE or DATETIME value.
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7))
For example,
set #datestamp := '2015-04-10'
SELECT FROM_DAYS(TO_DAYS(#datestamp) -MOD(TO_DAYS(#datestamp) -2, 7))
yields the value 2015-04-06.
So, if you have a table called sale you can add up sales by week like this:
SELECT SUM(amount) weekly_amount,
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7)) week_beginning
FROM sale
GROUP BY FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -2, 7))
This is a very convenient way to handle things, because it's robust over end-of-year transitions. The WEEK() function doesn't work quite as well.
If your business rules say that your weeks begin on Sunday rather than Monday, use -1 rather than -2, as follows.
FROM_DAYS(TO_DAYS(datestamp) -MOD(TO_DAYS(datestamp) -1, 7))
The system is as such. Tutors provide their availability (Monday - Sunday) and the time frame they are available on that day (0700 - 1400) (ie: 7am - 2pm).
I am trying to figure out the best way to store and search through this information to find available tutors. Searching only needs to be done on a daily system (ie: day of the week - mon, tues, wed, etc).
My planned infrastructure:
//Tutor Availability
---------------------------------------------------------------------------
tutorID | monday | tuesday | wednesday | thursday | friday |
---------------------------------------------------------------------------
27 | 0700-1200 | NULL | 1400-1800 | NULL | NULL |
---------------------------------------------------------------------------
35 | NULL | 1400-1600 | NULL | NULL | 1100-1900 |
//Scheduled tutor sessions
------------------------------------
tutorID | day | time |
------------------------------------
27 | monday | 0700-0900 |
------------------------------------
35 | friday | 1300-1500 |
Query: SELECT tutorid FROM tutoravailability WHERE 'monday'=... is available between 0900-1100 and is not in scheduled tutor session.
I have been searching forever about how I can search through (and store) these time intervals in MySQL. Is this the best way to store the time intervals of a 24 hours day? Will it even be possible to search between these intervals? Am I approaching this from the wrong way? Any insight is appreciated.
Updated Infrastructure
//Tutor Availability
-----------------------------------------------------
tutorID | day | start_time | end_time | PK |
-----------------------------------------------------
27 | mon | 0700 | 1200 | 1 |
-----------------------------------------------------
27 | fri | 1400 | 1800 | 2 |
-----------------------------------------------------
35 | tue | 1100 | 1600 | 3 |
//Scheduled tutor sessions
--------------------------------------------------------
tutorID | day | start_time | end_time | PK |
--------------------------------------------------------
27 | mon | 0800 | 1000 | 1 |
--------------------------------------------------------
27 | fri | 1600 | 1800 | 2 |
So with this system it will be much simpler to search for available times. However I am still at a loss as to how to compare the availability against the scheduled lessons to ensure no overlap.
SELECT tutorID
FROM tutoravailability WHERE day = 'fri'
AND start_time <= '1400'
AND end_time >= '1530'
Now I don't understand how I would compare this query against the Scheduled tutor sessions table to avoid duplicate bookings.
Final Update
To ensure their are no overlapping of the Scheduled Tutors sessions I will use the MySQL BETWEEN clause to search for the start and end time.
If you store the time interval using two columns it will be much easier for you to perform a search using sql query.
i.e. tutorID, day, startTime, endTime
You can use a bit flag to indicate the availability (24 bit) and scheduled time (24 bit). Then you can use 24 bit to represent the available hours and scheduled hours for each day.
In the Tutor Availability table, let's say '1' stands for Available in and '0' stands for unavailable. In the Scheduled table, '0' stands for Scheduled, '1' stands for Unscheduled.
So the available interval 0900-1100 can be stored as POW(2,9) | POW(2,10) | POW(2,11); the scheduled 1000-1200 can be stored as ^(POW(2,10) | POW(2,12))
Then the following query can give your the availability of on tutor - available on Monday between 09 am to 11 am:
SELECT ta.tutorid FROM tutoravailability ta, tutorscheduled ts
WHERE ta.tutorid = ts.tutorid AND ts.day = 'monday'
AND (ta.monday & ts.time & (POW(2,9) | POW(2,10) | POW(2,11))) = (POW(2,9) | POW(2,10) | POW(2,11))