MYSQL - Select Query Between DATE_ADD and DATE_SUB - php

I have a booking in my mysql booking table bookings as below:
start_date = 2013-03-04
end_date = 2013-03-08
I want to check if a particular day (in this case 2013-03-04) falls between the start and end dates in the booking(s) - BUT i want to add one day to the start date and subtract 1 day from the end date.
So instead of searching between 2013-03-04 and 2013-03-08
i want to search between 2013-03-05 and 2013-03-07
The following query below does the subtract 1 day from the end date but keeps the start date as 04. The search below should give no results but it is still using 04 as the start date and giving my the result of that booking. It is basically searching between [04] [05] [06] [07] when it should do [05] [06] [07]
$fd_query_params = array(
':day' => '2013-03-04
);
$query = "
SELECT
*
FROM
bookings as bb
WHERE
:day BETWEEN
DATE_ADD(bb.start_date, INTERVAL 1 DAY)
AND
DATE_SUB(bb.end_date, INTERVAL 1 DAY)
";

Not php expert myself but should there be more than I notice there is only a single quote around the :day string. It would be good to see the output to verify what the start_date and end_date is

Related

How to SELECT a date between two dates

How can I select from mysql with php a range between 2 dates?
The working day, start for example, at 7:00 am of 2022-01-01 and ends at 2:00 am of 2022-01-02. I want that all collected datas from 00:00 to 2:00 am of 2022-01-02 are grouped inside previous date.
Now I use this query
SELECT date_format(dateAdded,"%m-%d") as mth,COUNT(productID) as total, productID FROM statisticsNW WHERE userID = "35" AND productID = "1193'" AND YEAR(dateAdded) = "2022" AND month(dateAdded) = "01" GROUP by year(dateAdded),month(dateAdded), day(dateAdded) ORDER by year(dateAdded),month(dateAdded)
and the result is this but the "total" is wrong because is from 00:00 to 23:59 of the same day. The correct query the I want is from 7:00 to 6:59 of the next day. But from 00:00 to 6:59 datas must be counted in the previous day.
you can add 5 hours to the start_time and end_time, so the it appears the shift starts at midnight
select DATEDIFF(HH,cast('2022-01-24 19:00:00' as datetime),cast('2022-01-25 00:00:00' as datetime)) as time_5_hrs
select dateadd(HOUR,5,cast('2022-01-02 19:00:00' as datetime)) as starttime, dateadd(HOUR,5,cast('2022-01-03 02:00:00' as datetime)) as endtime,datediff(HH,dateadd(HOUR,5,cast('2022-01-02 19:00:00' as datetime)),dateadd(HOUR,5,cast('2022-01-03 02:00:00' as datetime))) diff
By doing this you can get both date are the same and you will be able to group it as single day.
I have solved
SELECT DATE_SUB(DATE_ADD("2017-06-15 5:30:00", INTERVAL 24 HOUR), INTERVAL 1 MINUTE);

Calculate Number of worked_days in Given month from Deployment data (Mysql/PHP)

I am working on Payroll System where an employee can be deployed on projects from any_date to any_date. Sample MySQL table below
id empid project_id start_date end_date
1 1 2 2016-11-05 15:10:22 2016-12-11 15:11:21
2 1 3 2016-12-13 15:26:10 2016-12-20 15:29:40
3 1 2 2016-12-23 15:31:46 2017-01-18 15:32:35
Now, if I want to calculate the number of days in given month worked on all projects, I am using Eloquent which translates to below query(I verified in DB::getQueryLog()):
SELECT
*
FROM
payroll_project_tracks
WHERE
empid = 1
AND '2016-12-01 00:00:00' BETWEEN start_date AND end_date
AND '2016-12-31 23:59:59' BETWEEN start_date AND end_date
After getting the rows that have deployments of given month (month = Dec 2016 here), I want to calculate Number of Days worked on all projects in a given month.
I am getting no results with the above query. Can anyone correct me or let me know if there is some better way of doing this.
I think that the query should be:
SELECT *
FROM payroll_project_tracks
WHERE
empid = 1 AND
start_date <= '2016-12-31 23:59:59' AND
end_date >= '2016-12-01 00:00:00'
This query will return the 3 rows you provided, but will cut out the following:
4 1 2 2017-01-01 15:31:46 2017-01-18 15:32:35
is this ok?

Get count of several times slots on between given two mysql time slots within datetime field

I have several in data and out date mysql datetime values. I need to return total count from given dateperiod and given time slot
Ex.
time
2012-02-01 10:00
2012-02-01 12:00
2012-02-01 14:00
2012-02-02 09:00
2012-02-02 10:00
2012-02-03 11:00
how to get data basis on time and date slot form datetime field as in this question i only want to get data from date 2012-02-01 to 2012-02-02 and time from 09:00 to 12:00 hence this should not provide the data of 2012-02-01 14:00 hope you got this now
you need only to add count(*) in your statement.
SELECT count(*) FROM users WHERE created_at BETWEEN '2012-02-01 09:00' AND '2012-02-02 12:00'
Try this -
SELECT count(*) as c FROM users WHERE created_at
BETWEEN '2012-02-01 09:00' AND '2012-02-02 02:00' AND
Time(c) BETWEEN '09:00' AND '02:00'
2012-02-01 14:00 is rightfully included in the result of your query, what you want to achieve can be done this way
SELECT * FROM users WHERE
(DATE(created_at) BETWEEN '2012-02-01' AND '2012-02-02')
AND
(TIME(created_at) BETWEEN '09:00' AND '12:00')
You have a typo in your query. The closing time is 14:00, not 12:00:
SELECT COUNT(*)
FROM users
WHERE created_at BETWEEN '2012-02-01 09:00' AND '2012-02-02 14:00' ;
EDIT:
If you are trying to limit the times and dates separately, then use two conditions:
SELECT COUNT(*)
FROM users
WHERE created_at >= '2012-02-01' AND created_at < '2012-02-03' AND
time(created_at) BETWEEN '09:00:00' AND '14:00:00' ;

Mysql query based on date?

I have a table like this
id | date | content
1 | 09-16-2013 | content 1 here
2 | 09-23-2013 | content 2 here
3 | 09-30-2013 | content 3 here
I would like to display the content for a week from that date. For example, the first content should start on 9/16/2013 and then show until 9/22/2013 mid night. then on next day, it changes to the content 2.
Same way,when I am on content 2, I want to display like "previous week content" and then show just the previous ones..I think I can do this by checking the current date and then anything below that has to be displayed.
I am not very good at these kind of mysql queries, please advise!
Regards
I guess you're looking for something like this
SELECT *
FROM table1
WHERE date BETWEEN CURDATE() + INTERVAL 0 - WEEKDAY(CURDATE()) DAY
AND CURDATE() + INTERVAL 6 - WEEKDAY(CURDATE()) DAY
This query will grab a row(s) where date column is within the boundaries of the current calendar week (from Monday to Sunday).
WEEKDAY() function returns the weekday index for date (0 = Monday, 1 = Tuesday, … 6 = Sunday). The expression
CURDATE() + INTERVAL 0 - WEEKDAY(CURDATE()) DAY
returns a date for Monday of the current calendar week and
CURDATE() + INTERVAL 6 - WEEKDAY(CURDATE()) DAY
returns a date for Sunday of the current calendar week.
Using BETWEEN in WHERE clause makes sure that a query returns only rows with date values that falls between these two dates (Monday through Sunday).
Note: Make sure that you have an index on date column. This query is index-friendly.
Sample output for today's date (09/19/2013):
+------+------------+----------------+
| id | date | content |
+------+------------+----------------+
| 1 | 2013-09-16 | content 1 here |
+------+------------+----------------+
UPDATE: To get records for previous calendar week you just substract 1 week interval from both values in BETWEEN
SELECT *
FROM table1
WHERE date
BETWEEN CURDATE() + INTERVAL 0 - WEEKDAY(CURDATE()) DAY - INTERVAL 1 WEEK,
AND CURDATE() + INTERVAL 6 - WEEKDAY(CURDATE()) DAY - INTERVAL 1 WEEK
Try this
SELECT * FROM table WHERE date BETWEEN '09-16-2013' AND '09-22-2013';
keyword is WEEK()
SELECT id,date, CONCAT('content ',WEEK(date),' to here') as content FROM table_name
SELECT *
FROM table
WHERE date BETWEEN '9/16/2013 00:00:00.00' AND '9/22/2013 00:00:00.00'
You can replace the week offset to your needs
SET #weekOffset = +2;
SELECT * FROM test
WHERE WEEK(`date`) = WEEK(NOW()) + #weekOffset;
See a working demo here
To select it dynamically, try something like
SELECT * FROM `yourTable` WHERE NOW() >= STR_TO_DATE(`date`, '%m-%d-%Y') ORDER BY STR_TO_DATE(`date`, '%m-%d-%Y') DESC LIMIT 1
or t
SELECT * FROM `yourTable` WHERE CURDATE() >= STR_TO_DATE(`date`, '%m-%d-%Y') ORDER BY STR_TO_DATE(`date`, '%m-%d-%Y') DESC LIMIT 1
sqlfiddle example - http://sqlfiddle.com/#!2/62982/4

Calculate total time of each user in single/per day - php/mysql

> Start stop pinnumber
> ---------------------------------------------------------
> 2012-03-14 13:22:17 2012-03-14 15:22:50 2001
> 2012-03-14 18:11:10 2012-03-14 19:10:10 2001
> 2012-03-15 07:20:10 2012-03-15 13:20:50 2001
>**2012-03-16 19:21:55 2012-03-17 02:55:22 2001** //on 16(19:21:55
to 23:59:59) and
//on 17(00 to 02:55:22)
> 2012-03-17 14:15:05 2012-03-17 17:44:50 2001
> 2012-03-18 19:11:10 2012-03-18 19:10:10 2002
> 2012-03-18 10:20:10 2012-03-18 13:20:50 2003
> 2012-03-18 11:20:10 2012-03-18 15:11:50 2001
Question:
How can I calculate total time of each user of per day ('start', 'stop') per day? Please see the above highlighted point. Suppose, If user 'start' today and stop it tomorrow then today hour are different and tomorrow hour are different?
right now i am using following query:-
SELECT SEC_TO_TIME( SUM( TIME_TO_SEC(TIMEDIFF(stop ,start ) ) ) ) AS time1, clock. * FROM table_name WHERE pin_number = '2001' GROUP BY DATE_FORMAT( start , '%W %M %Y' )
from above query i am getting per day records but when start date and stop date is different. it calculate total time not single day time but i need per day time.
I think I finally got there. You first need to get a set of days, which I obtain through a subquery that takes a UNION of the start and stop times (you could filter this for your pinnumber if desired in order to reduce the size of the JOIN).
One then joins each such date with those (start,stop) pairs that encompass that date (i.e. either start during the day, or the start of the day is between the start and stop time).
Finally, one groups by day and takes the sum of the amount of time between the start and end times, cutting off at the day start and end as appropriate (the magic 86400 is the number of seconds in a day = 24*60*60). Sadly this won't play nice with daylight savings, leap seconds, etc...
SELECT FROM_UNIXTIME(unixday, '%d/%m/%Y'), SUM(
LEAST( unixday+86400, UNIX_TIMESTAMP(Stop ))
- GREATEST(unixday , UNIX_TIMESTAMP(Start))
) AS Seconds
FROM table_name JOIN (
SELECT UNIX_TIMESTAMP(DATE(Start)) AS unixday FROM table_name
UNION
SELECT UNIX_TIMESTAMP(DATE(Stop )) AS unixday FROM table_name
) AS days ON (
UNIX_TIMESTAMP(Start) BETWEEN unixday AND unixday+86400
OR (unixday BETWEEN UNIX_TIMESTAMP(Start) AND UNIX_TIMESTAMP(Stop))
)
WHERE pinnumber = 2001
GROUP BY unixday;
See it on sqlfiddle.

Categories