I have a db table with a list of events
e.g.
starteventX = 2019-02-20 endeventX = 2019-03-15
starteventY = 2019-03-11 endeventY = 2019-05-28
I need to know if year 2019 and month 04 are in the event so I can prepare a monthly report
I tried
$mainlink = mysqli_query($db,"SELECT * FROM eventi WHERE ((year1 >= '$year') OR (year2 <= '$year'))
AND ((month1 >= '$month') OR (month2 <= '$month')) ") or merror($msg = mysqli_error($db));
but cant get the required info
As a concept (assuming the data is valid, i.e. the end of some event is always later than its start):
If you want at least a day of a given month be in the event:
SELECT * FROM e
WHERE e.startevent <= '2019-04-30' AND e.endevent >= '2019-04-01'
If you want the entire month be in the event:
SELECT * FROM e
WHERE e.startevent <= '2019-04-01' AND e.endevent >= '2019-04-30'
If you want overlapping time intervals, then it is something like this:
SELECT e.*
FROM eventi e
WHERE e.startevent < '2019-05-01' AND -- starts before the end of the month
e.endevent > '2019-04-01' -- ends after the start of the month
Related
I'm trying to find to which shift belongs a datetime field.
Shifts are defines as time, and I have a startingHour and endingHour.
The query
SELECT * FROM shifts WHERE TIME('2009-11-20 06:35:00') BETWEEN '06:00:00' and '19:00:00'
works perfect, but when the shift is set to start 19:00:00 to 06:00:00 and the time is 23:35:00 it doesn't return anything
WHERE TIME('2009-11-20 23:35:00') BETWEEN '19:00:00' and '06:00:00'
that line isn't returning anything though I do have records on the table
Thanks
That's the shifts table.
if I query this:
SELECT
a.ID,
b.Nombre
FROM turnos a
JOIN operarios b ON a.oID = b.oId
WHERE a.uId = 1
AND (TIME('2019-11-22 18:23:00') BETWEEN a.horaInicio AND a.horaFin )
LIMIT 1
I get the proper result, but when I query this:
SELECT
a.ID,
b.Nombre
FROM turnos a
JOIN operarios b ON a.oID = b.oId
WHERE a.uId = 1
AND (TIME('2019-11-22 02:45:00') BETWEEN a.horaInicio AND a.horaFin )
LIMIT 1
I get no result.
These are two cases: start time < end time and start time > end time. You need something like this:
where (start_time < end_time and $t >= start_time and $t < end_time)
or (start_time >= end_time and ($t < start_time or $t >= end_time))
Since '19:00:00' is greater than '06:00:00' then:
BETWEEN '19:00:00' and '06:00:00'
returns 0 (false) and you get no rows.
One way to get the results that you want is to use CASE like this:
.................
AND 1 = CASE
WHEN a.horaInicio <= a.horaFin THEN TIME('2019-11-22 02:45:00') BETWEEN a.horaInicio AND a.horaFin
ELSE (TIME('2019-11-22 02:45:00') BETWEEN a.horaInicio AND '23:59:59')
OR (TIME('2019-11-22 02:45:00') BETWEEN '00:00:00' AND a.horaFin)
END
I would like to select all records before 2014-03-22 date:
where date < 2014-03-22 // what I need
but below code doesn't see 2013 year's records :
SELECT * FROM `tractions` WHERE YEAR(date) <= 2014 AND MONTH(date) <= 3 and DAY(date) <= 22 and succ = 1
Is there anything wrong with:
SELECT * FROM tractions
WHERE date < '2014-03-22' -- place the date, correctly formatted, in quotes
Since this comparison doesn't use any functions, it will also allow you to use any indices setup on the date column.
I have check room is exists between two time for particular date.
I have try following two query its run some time rights but, when i select 10:00 AM to 12:00 PM at time wrong results means not return any records.
QUERY-1 :
SELECT 1 FROM `timetable_details` WHERE (
((`td_from` <= '10:00:00') AND (`td_to` > '10:00:00'))
OR
((`td_from` < '12:20:00') AND (`td_to` >= '12:20:00'))
) AND ((`td_room`='1') AND (`td_date`='2016-01-25'))
QUERY-2 :
SELECT 1 FROM `timetable_details` WHERE (
(`td_from` > '07:00:00') AND (`td_to` < '08:00:00')
) AND ((`td_room`='1') AND (`td_date`='2016-01-25'))
I have get td_id = 4 number row but is not returns.
You can use between with OR condition for both columns as below :
SELECT 1 FROM `timetable_details` WHERE (((((`td_from` BETWEEN '10:00:00' AND '12:30:00') OR (`td_to` BETWEEN '10:00:00' AND '12:30:00')) AND ((`td_room`='1') AND (`td_date`='2016-01-25') AND (`td_status` IS NULL))) AND (`td_from` <> '12:30:00')) AND (`td_to` <> '10:00:00'))
I have an app that displays ads from campaigns. I limit display of each campaign's set of ads to a specific date range per campaign. My "campaigns" table looks like this:
campaigns
id : integer
start_date : date
end_date : date
I now need to be able to optionally limit the display of campaign ads to a specific time range each day. So now my table looks like
campaigns
id : integer
start_date : date
end_date : date
start_time : time, default: null
end_time : time, default: null
And so my [MySQL] query looks like this:
SELECT
ads.*
FROM
ads
INNER JOIN campaigns ON campaigns.id = ads.campaign_id
WHERE
campaigns.start_date <= "2014-08-05" AND
campaigns.end_date >= "2014-08-05" AND
campaigns.start_time <= "13:30"
campaigns.end_time >= "13:30";
(Dates and times are actually injected using the current date/time.)
This works fine. However, because I store start_time and end_time in UTC time, sometimes end_time is earlier than start_time; for example, in the database:
start_time = 13:00 (08:00 CDT)
end_time = 01:00 (20:00 CDT)
How can I adjust the query (or even use code) to account for this?
The problem is harder than it looks because either the campaigns or the comparison time span can go over the date boundary. Then, there is an additional complication. If the campaign says that it is running until 1:00 a.m., is the end date on the current date or the next date? In other words, for your example, 1:00 a.m. on 2014-08-06 should really be counted as 2014-08-05.
My recommendation, then, is to switch to local time. If your campaigns don't span midnight, then this should solve your problem.
If you only care about the campaigns themselves spanning midnight, you can do something like:
WHERE campaigns.start_date <= '2014-08-05' AND
campaigns.end_date >= '2014-08-05' AND
((campaigns.start_time <= campaigns.end_time and
campaigns.start_time >= '13:00' and
campaigns.end_time <= '18:00'
) or
(campaigns.start_time >= campaigns.end_time and
(campaigns.start_time >= '13:00' or
campaigns.end_time <= '18:00'
)
)
Note that when the end_time is greater than the start time, then you want times greater than the start time or less than the end time. In the normal case, you want times greater than the start time and less than the end time.
You can do something similar if you only care about the comparison time period. Combining the two seems quite complicated.
You just can check the both ways.
SELECT
ads.*
FROM
ads
INNER JOIN campaigns ON campaigns.id = ads.campaign_id
WHERE "2014-08-05" BETWEEN campaigns.start_date AND campaigns.end_date
AND ("13:30" BETWEEN campaigns.start_time AND campaigns.end_time
OR "13:30" BETWEEN campaigns.end_time AND campaigns.start_time)
If your range is 08:00 to 16:00 the first part will find your results and the second one none because the range is wrong.
If your range is 16:00 to 08:00 the first part won't find any result and the second one will give them you.
So, Gordon Linoff's answer sent me in the right direction. Here's the query that worked:
SELECT
ads.*
FROM
ads
INNER JOIN campaigns ON campaigns.id = ads.campaign_id
WHERE
"2014-08-05" BETWEEN campaigns.start_date AND campaigns.end_date AND
(campaigns.start_time IS NULL OR campaigns.end_time IS NULL) OR (
((campaigns.start_time < campaigns.end_time AND
campaigns.start_time <= "13:30:00" AND campaigns.end_time >= "13:30:00") OR
(campaigns.start_time > campaigns.end_time AND
((campaigns.start_time <= "13:30:00" AND campaigns.end_time <= "13:30:00") OR
(campaigns.start_time >= "13:30:00" AND campaigns.end_time >= "13:30:00"))))
);
I have table ORDERS where is stored data about orders with their status and the date of order. I would like to search all orders with specified status and which was made yesterday after 3pm untill today 4pm. The query will run in different times (10am, 3pm, 5 pm... regardless).
So on example: if I run the query today (13.05.2014) I would like to get all orders made from 2014-12-05 15:00:00 untill 13-05-2015 16:00:00
The date is stored in format: YYYY-MM-DD HH:MM:SS
What I got is:
select *
from orders
where status = 'new'
and (
(
date_add(created_at, INTERVAL 1 day) = CURRENT_DATE()
and hour(created_at) >= 15
) /*1*/
or (
date(created_at) = CURRENT_DATE()
and hour(created_at) <= 16
) /*2*/
)
And I get only orders made today - like only the 2nd condition was taken into account.
I prefer not to use created >= '2014-05-12 16:00:00' (I will not use this query, someone else will).
When you add an interval of 1 day to the date/time, you still keep the time component. Use date() for the first condition:
where status = 'new' and
((date(date_add(created_at, INTERVAL 1 day)) = CURRENT_DATE() and
hour(created_at) >= 15
) /*1*/ or
(date(created_at) = CURRENT_DATE() and
hour(created_at) <= 16
) /*2*/
)
And alternative method is:
where status = 'new' and
(created_at >= date_add(CURRENT_DATE(), interval 15-24 hour) and
created_at <= date_add(CURRENT_DATE(), interval 16 hour)
)
The advantage of this approach is that all functions are moved to CURRENT_DATE(). This would allow MYSQL to take advantage of an index on created_at.