Mysql select current time between two columns - mysql

I have a schedule table in which I have two columns time_from and time_to with values in the 24 hour format like if the from and to are 9 Pm to 1am than the time_from and time_to would be 21 and 1 respectively.
Now I need to check if the current time falls between these two columns
If the time is 11 Pm now I should get the column whose in which column value in between 11 Pm that is 23 and 1
CREATE TABLE `ace_rp_inventory_locations_night` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`time_from` varchar(255) DEFAULT NULL,
`time_to` varchar(255) DEFAULT NULL
);
INSERT INTO ace_rp_inventory_locations_night (id, name, time_from, time_to)
VALUES (1, 'test', '23','1');
please check sql fiddle
this query works
SELECT *
FROM `ace_rp_inventory_locations_night`
WHERE time_from_1 <= '23'
AND time_to_1 >= '23'
if the time is in 24 Hours range that is 20 and 24 but the value for 1am is 1 and the above query does not work because 23 and 1 does not full fill the condition I am checking it with the current time so if the time is 2am I have to pass 2 in the query.
How can I use the current time and use it to query between two columns?

You can use:
SELECT *
FROM `ace_rp_inventory_locations_night`
WHERE (time_from_1 <= time_to_1 AND 23 between time_from_1 and time_to_1) OR
(time_to_1 > time_to_1 AND 23 NOT BETWEEN time_from_1 and time_to_1);
Note: This uses BETWEEN which affect how the end points of the ranges are handled. Your question doesn't specify what to do. You should probably be explicit about the inequalities.

Related

What's the best way to concat my multiple columns into datetime, when I have mixed data in columns, like both varchar and Integer?

So data is a table with the date and time info split into 4 columns, some varchar, others integer:
Year Month Day Time
2022 May 20 18:43
1982 Feb 01 00:23
1942 Jan 13 16:17
Month and time are varchar, and year and day are integer.
I have to query via MYSQL to find certain dates, and it would be easier if the field I search was datetime like '2022-05-20 18:43'
I have searched all day yesterday and find a lot of examples that come close to what I need but not fit exactly, and I'm not good enough with MYSQL to figure this out.
I assume I have to concat() at some point, but then there is the CONVERSIONS I have to make on the varchar's
I want to run a query that creates a NEW COLUMN in the DB which is datetime and then I can just query straightforward. So create a new column called 'date2' which is datetime, which I already created, just have to concat somehow and then move each rows data to it. Like this:
Year Month Day Time Date2
2022 May 20 18:43 2022-05-20 18:43
1982 Feb 01 00:23 1982-02-01 00:23
1942 Jan 13 16:17 1942-01013 16:17
Here is the Table Schema:
CREATE TABLE `lunar2` (
`year` int(4) unsigned NOT NULL,
`month` varchar(3) NOT NULL,
`day` int(2) NOT NULL,
`time` time NOT NULL,
`sign` varchar(15) NOT NULL,
`other` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Here is the code that worked. I thank the person who provided the code:
UPDATE table1 SET
other = STR_TO_DATE(CONCAT_WS(' ', Year, Month, Day, Time), '%Y %M %d %H:%i:%s');
Try using STR_TO_DATE() to create a DATETIME value.
ALTER TABLE yourTable ADD COLUMN Date2 DATETIME;
UPDATE yourTable SET
Date2 = STR_TO_DATE(CONCAT_WS(' ', Year, Month, Day, Time), '%Y %b %d %H:%i:%s');
UPDATE: Since your Time field is actually of type TIME, then we need to use %H:%i:%s to correctly parse it.
Here is an example of what you are trying to do.
When converting string to date it is important to get the format string right, otherwise we get a null value.
create table datess(
y int,
m varchar(3),
d int,
t varchar(5));
insert into datess (y,m,d,t)values
(2022 ,'May', 20 ,'18:43'),
(1982 ,'Feb', 01 ,'00:23'),
(1942 ,'Jan', 13 ,'16:17');
SELECT
STR_TO_DATE(
CONCAT(y,'-',m,'-',d,' ',t),
'%Y-%M-%d %H:%i') date_format
FROM datess;
| date_format |
| :------------------ |
| 2022-05-20 18:43:00 |
| 1982-02-01 00:23:00 |
| 1942-01-13 16:17:00 |
db<>fiddle here

Get records between Two Dates with overlapping time intervals

I have the following database
CREATE TABLE `table` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`time` bigint(20) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`messages` varchar(2000) NOT NULL,
PRIMARY KEY (`id`)
)
INSERT INTO `table` VALUES (1,1467311473,"Jim", "Jim wants a book"),
(2,1467226792,"Tyler", "Tyler wants a book"),
(3,1467336672,"Phil", "Phil wants a book");
I need to get the records between date 29 Jun 2016 and 1 July 2016 for time intervals 18:59:52 to 01:31:12.
I wrote a query but it doesn't return the desired output
SELECT l.*
FROM table l
WHERE ((time >=1467226792) AND (CAST(FROM_UNIXTIME(time/1000) as time) >= '18:59:52') AND (CAST(FROM_UNIXTIME(time/1000) as time) <= '01:31:12') AND (time <=1467336672))
Any suggestions??
As I understand it, you're simply interested in all periods greater than '2016-06-29 18:59:52' and less than '2016-07-01 01:31:12' where the time element is NOT between '01:31:12' and '18:59:52'
I think you can turn that logic into sql without further assistance
Ah, well, here's a fiddle - left out all the from_unixtime() stuff because it adds unnecessary complication to an understanding of the problem - but adapting this solution to your needs is literally just a case of preceding each instance of the column time with that function:
http://rextester.com/OOGWB23993
If i got it right
SELECT l.*
FROM `table` l
WHERE time >=1467226792
AND time <=1467336672
AND CAST(FROM_UNIXTIME(time/1000) as time) >= '18:59:52'
AND FROM_UNIXTIME(time/1000) <= DATE_ADD(DATE_ADD(DATE_ADD(CAST(FROM_UNIXTIME(time/1000) as date), INTERVAL 25 HOUR), INTERVAL 31 MINUTE), INTERVAL 12 SECOND)

What's wrong with this simple MySQL syntax? Summing the dates

Among the rest, I've got three columns in my table:
start- timestamp, the default value is CURRENT_TIMESTAMP
duration- datetime, usually 0000-00-07 00:00:00 (one week)
end - timestamp, the default value is 0000-00-00 00:00:00
Here's what I do:
UPDATE `banners` SET `end` = `start` + `duration` WHERE `id` = 93
No errors appear, the id is exact - but the operation doesn't execute, the end field just remains at zeros.
What's wrong? Any quotes, brackets needed? I also tried making the middle field the timestamp type as well with no result.
Very possible, just a little ugly in terms of code...
UPDATE `banners`
SET `end` = FROM_UNIXTIME(UNIX_TIMESTAMP(`start`) + (UNIX_TIMESTAMP(`duration`) - UNIX_TIMESTAMP('1970-01-01 00:00:00')),'%Y-%d-%m %h:%i')
WHERE `id` = 93
...you just need to convert everything to seconds, add the duration from teh second one and then convert back to a datetime string for setting :)
You cannot add DATETIME values the same way you add numbers. What's the meaning of April 25, 2016 added to January 5, 2016?
You should store your durations using the smallest time unit that can be used to represent them as integer numbers and use the MySQL DATE_ADD() function instead of the addition.
For example, if duration is 1 WEEK then you can use any of:
UPDATE `banners` SET `end` = DATE_ADD(`start`, INTERVAL 1 WEEK) WHERE `id` = 93
UPDATE `banners` SET `end` = DATE_ADD(`start`, INTERVAL 7 DAY) WHERE `id` = 93
UPDATE `banners` SET `end` = DATE_ADD(`start`, INTERVAL 168 HOUR) WHERE `id` = 93
If duration is usually 1 week, you can use DATE_ADD() function of MySql
DATE_ADD(start,INTERVAL 7 DAY)
Hope that helps

Calculating working hours for each weekday between date range

I have a table timeandattandance with following fields
TAId int(11) NOT NULL AUTO_INCREMENT,
PostId int(11) NOT NULL,
PositionId int(11) NOT NULL,
CreatedBy int(11) NOT NULL,
ModifiedBy int(11) NOT NULL,
CreatedDate datetime NOT NULL,
ModifiedDate datetime NOT NULL,
TimeIn datetime NOT NULL,
TimeOut datetime DEFAULT NULL,
TimeBilled tinyint(1) NOT NULL DEFAULT '0',
DeviceId varchar(50) DEFAULT NULL,
UserId int(11) DEFAULT NULL,
oldid varchar(45) DEFAULT NULL,
FromCallIn tinyint(1) DEFAULT '0'
I need to get working hours for each user for each day grouped by week ending date between a date range. that is I have been given a date range. Firstly I need to find out that timein will be between this date range then I need to get all week ending dates and then for every week I need to calculate working hours for each day.
Also while calculating the working hours I need to check if difference between timein and timeout is more than one day then these working hours will be separated for two days instead of one.
I know it's bit complex and if require more explanation please let me know.
Here's an example/demonstration of one possible approach:
SELECT r.dt + INTERVAL 7-DAYOFWEEK(r.dt) DAY AS week_ending
, t.userid
, r.dt
, SUM(TIMESTAMPDIFF(SECOND
,GREATEST(r.dt,t.timein)
,LEAST(r.dt+INTERVAL 1 DAY,t.timeout)
)
)/3600 AS hours_worked
FROM ( SELECT '2014-09-28' AS rb, '2014-10-11' AS re) dr
JOIN ( SELECT DATE(i.timein) AS dt FROM mytable i
UNION
SELECT DATE(o.timeout) FROM mytable o
) r
ON r.dt BETWEEN DATE(dr.rb) AND DATE(dr.re)
JOIN mytable t
ON t.timein < r.dt+INTERVAL 1 DAY
AND t.timeout > r.dt
GROUP BY t.userid, r.dt
ORDER BY week_ending, t.userid, r.dt
NOTE: The week_ending returns the date of the Saturday following (or of) the work date.
The date range is specified in the inline view dr (date range), range begin date is column rb, the range end date is column re. This example shows a two week range, starting on Sunday 2014-09-28 for two full weeks, including time worked on Saturday 2014-10-11. (The value for re could be derived as an integer number of days from rb, to get 14 full days, `rb + INTERVAL 13 DAY)
Only hours worked on these dates, or on days between these dates, are reported. A given userid that did not have any work "time" on a given date will not have a row returned for that date. (The query could be easily tweaked to return rows for all employees for all dates in the range, and returning zeros.)
Absent a "cal" calendar table that contains all date values, we can get a distinct list of date values in the range from the table itself; this could be relatively expensive operation for a large number or rows in the table. This won't return date values that don't appear in the timein or timeout columns. (If there's a work period of over 24 hours, e.g. starting on Monday and ending on Wednesday. and there are no other rows that have a timein or timeout on Wednesday, the 24 hours worked that day will be omitted... that's likely an extreme corner case. Having a distinct list of all possible date value available in a calendar table avoids that problem.)
FOLLOWUP
From your comment it sounds like you need a cross product between a distinct list of days, and a distinct list of users, then an outer join to the working hours table.
JOIN ( distinct_list_of_dates_r ) r
ON ( r_in_specified_week )
CROSS
JOIN ( distinct_list_of_userid_u ) u
LEFT
JOIN mytable t
ON ( t_userid_matches_u )
AND ( t_times_matches_r )
And then GROUP BY the userid from u, rather than from t. You'll likely want to replace a NULL value returned from hours_worked with a 0. The MySQL IFNULL function is convenient for that, IFNULL(expr,0) is shorthand for CASE WHEN expr IS NULL THEN 0 ELSE expr END. If you want total hours for the entire week, rather than by individual days, then do the GROUP BY on the week_ending expression, rather than on the individual date.

Date Difference Between SYSDATE and Date stored in MM-DD format

I am setting up a simple reminder system, and am using a MySQL table to store the dates.
The key things I need to store for the reminder date are the Day of the Month, and the Month.
However, the user has to pick the values from a DatePicker field, as taken from here:
http://www.eyecon.ro/bootstrap-datepicker/
Therefore, if the user wanted a reminder date of 2nd September, the date is stored in a a "date" field the database in YYYY-MM-DD format as 2014-09-02.
The problem I am having is working out when that date is due within the next month.
Here is my sample table:
CREATE TABLE `test_table` (
`fldID` int(11) NOT NULL AUTO_INCREMENT,
`fldDate` date DEFAULT NULL,
`fldDateVarChar` varchar(255) DEFAULT NULL,
PRIMARY KEY (`fldID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Some example data:
insert into `test_table`(`fldID`,`fldDate`,`fldDateVarChar`) values (1,'2014-08-28','08-28');
insert into `test_table`(`fldID`,`fldDate`,`fldDateVarChar`) values (2,'2016-10-09','10-09');
insert into `test_table`(`fldID`,`fldDate`,`fldDateVarChar`) values (3,'2014-01-23','01-23');
insert into `test_table`(`fldID`,`fldDate`,`fldDateVarChar`) values (4,'2015-09-18','09-18');
Sample Data:
fldID fldDate fldDateVarChar
------------------------------------------
1 2014-08-28 08-28
2 2016-10-09 10-09
3 2014-01-23 01-23
4 2015-09-18 09-18
Desired output:
fldID TODAYS_DATE CalcDate Difference
--------------------------------------------------------------------
1 2014-08-23 2014-08-28 -5
2 2014-08-23 2014-10-09 -47
3 2014-08-23 2014-01-23 212
4 2014-08-23 2014-09-18 -26
For the above, the 1st and 4th rows are relevant / useful in that the due dates fall within the next month.
The user picks a data using a date picker. I am only interested in the month and day. The year is not important.
I also store the MM-DD value in a VARCHAR field, just in case I need it.
I would like to work out an SQL statement to calculate the difference in days between SYSDATE (or NOW()) and the MM-DD part of the user's reminded date.
I cannot use e.g. DATEDIFF without also appending the year to the user's reminder date.
e.g. for a MM-DD value of "08-28" I would need something like:
SELECT DATEDIFF(NOW(),'2014-08-28') FROM DUAL;
But if I ran it in a years time, it would need to be:
SELECT DATEDIFF(NOW(),'2015-08-28') FROM DUAL;
That's what I'm having trouble with.
Can I achieve this in MySQL?
Maybe this works for you:
SELECT fldID,
DATE_FORMAT(NOW(), '%Y-%m-%d') AS TODAYS_DATE,
concat(year(now()),'-',fldDateVarChar) AS CalcDate,
DATEDIFF(NOW(), concat(year(now()),'-',fldDateVarChar)) AS Difference
FROM test_table
Test it here: http://sqlfiddle.com/#!2/098372/5/0