List of days with events that occur on that day - mysql

I have a table of events, each of which has a start date and an end date.
I need to display a list of days and show which events are occurring on each day.
E.g. Say I have on event that runs mon-wed and another that runs tues-thurs I'm trying to create a table like so:
Mon: Event 1
Tue: Event 1, Event 2
Wed: Event 1, Event 2
Thu: Event 2
The only way I can see to do this is either by running a query for each day or by loading all events for given date range and then duplicating them in my code if they last for more than one day. Both approaches seem hacky and I'm sure I'm missing something.
Is there a neater way to do this?
Structure:
id INT
name VARCHAR
start_date DATE
end_date DATE
Current query (slightly simplified because this database structure is appalling):
SELECT *
FROM events
WHERE start_date <= $somedate
AND end_date >= $somedate
...where $somedate is a given date. (Yes, I am escaping it properly in my code!)

Select your events for a particular date range (I assume a particular month). Then loop over the days in that month and have another, inner loop that displays any events that occur on that date.
<?php
$events = getEvents(); // some function that returns events from database
echo '<ol class="calendar">';
for ($i = 1; $i <= cal_days_in_month(); $i++) {
echo '<li>';
$beginning = mktime(0, 0, 0, date('n'), $i, date('Y'));
$end = mktime(23, 59, 59, date('n'), $i, date('Y'));
$events_on_day = array();
foreach ($events as $event) {
if ($event->start_date <= $end && $event->end_date >= $beginning) {
$events_on_day[] = $event;
}
}
if ($events_on_day > 0) {
echo '<ul>';
foreach ($events_on_day as $event_on_day) {
echo '<li>' . $event_on_day->name . '</li>';
}
echo '</ul>';
}
}
echo '</ol>';
?>

There's probably a better way, but off the top of my head I would say to create a table of possible dates, then simply
select * from events
inner join possibleDates on possibleDates.Date >= start_date and possibleDates.Date <= end_date

First you'll propably have to get all dates between start_date and end_date of each event.
Put the in a temp. table like:
|Weekday| Event_name|
|Mo | Event1 |
|Tu | Event1 |
|We | Event1 |
|We | Event2 |
|Th | Event2 |
|Fr | Event2 |
and then group_concat the events by group by on weekday.
This link will help you to get the dates between start and end date of each event.:
Get a list of dates between two dates

You can do it in one query if you must, though I would advise getting a weekday-table like Jan Zeiseweis also suggests. Working SQLfiddle: http://www.sqlfiddle.com/#!2/e618d9/1/0
SELECT wk.day, GROUP_CONCAT(e.name, '') events
FROM (
SELECT 'Monday' day, 0 dayIndex
UNION
SELECT 'Tuesday' day, 1 dayIndex
UNION
SELECT 'Wednesday' day, 2 dayIndex
UNION
SELECT 'Thursday' day, 3 dayIndex
UNION
SELECT 'Friday' day, 4 dayIndex
UNION
SELECT 'Saturday' day, 5 dayIndex
UNION
SELECT 'Sunday' day, 6 dayIndex
) wk
LEFT JOIN Events e
ON WEEKDAY(e.start) <= wk.dayIndex
AND WEEKDAY(e.end) >= wk.dayIndex
GROUP BY wk.day ORDER BY wk.dayIndex

Related

Return Results for current or next weekend

I'm creating a fixture list for football and would like to create a page "weekend fixtures".
I have managed the following
SELECT * FROM events WHERE DAYOFWEEK(event_time) = 7
or DAYOFWEEK(event_time) = 1
or (DATE_FORMAT(event_time, "%T") > '17:30:00' AND DAYOFWEEK(event_time) = 6)
The above code works in returning fixtures for all weekends. But I need either the current or next.
Any advice would be appreciated.
you can use WEEK function from mysql
This would check id´f event timestamp is in this or the next week
SELECT * FROM events WHERE (DAYOFWEEK(event_time) = 7
or DAYOFWEEK(event_time) = 1
or (DATE_FORMAT(event_time, "%T") > '17:30:00' AND DAYOFWEEK(event_time) = 6))
AND ((WEEK(event_time) = WEEK(Now()) ) OR (WEEK(event_time) = WEEK(Now()) +1 ))

Query database for Current Week Results [duplicate]

I have table temp with structure on sqlfiddle:
id(int 11 primary key)
name(varchar 100)
name2(varchar 100)
date(datetime)
I would like get record on this week, example if now 21.11.2013 i would like all rows on 18.11.2013 to 24.11.2013(on week)
Now I see next algorithm:
obtain weekday
calculate how many days ago was Monday
calculate the date Monday
calculate future date Sunday
make a request on date
Tell me please, is exist a shorter algorithm (preferably in the query MySQL)?
ADD Question is: Why this query select record on date 17.11.2013(Sunday) - 23.11.2013(Saturday) and how get records on date 18.11.2013(Monday) - 24.11.2013(Sunday) ?
query:
select * from temp
where yearweek(`date`) = yearweek(curdate())
Thanks!
Use YEARWEEK():
SELECT *
FROM your_table
WHERE YEARWEEK(`date`, 1) = YEARWEEK(CURDATE(), 1)
Use YEARWEEK. If you use WEEKOFYEAR you will get records of previous years also.
SELECT id, name, date
FROM table
WHERE YEARWEEK(date)=YEARWEEK(NOW());
For selecting records of day, week and month use this way:
function my_func($time, $your_date) {
if ($time == 'today') {
$timeSQL = ' Date($your_date)= CURDATE()';
}
if ($time == 'week') {
$timeSQL = ' YEARWEEK($your_date)= YEARWEEK(CURDATE())';
}
if ($time == 'month') {
$timeSQL = ' Year($your_date)=Year(CURDATE()) AND Month(`your_date`)= Month(CURDATE())';
}
$Sql = "SELECT * FROM your_table WHERE ".$timeSQL
return $Result = $this->db->query($Sql)->result_array();
}
You can do it by following method
SELECT DATE_FORMAT("2017-06-15", "%U");
Get number of week (From 00 to 53 )
Where (Sunday 1st day and Monday last day of week)
May be useful for you.
example:
SELECT DISTINCT DATE_FORMAT('dates', '%U') AS weekdays FROM table_name;
The short solution would be this:
SELECT * FROM my_table WHERE DATE_FORMAT("2021-08-19 15:40:33", "%U") = WEEK(CURDATE());

MySQL: How to select records for this week?

I have table temp with structure on sqlfiddle:
id(int 11 primary key)
name(varchar 100)
name2(varchar 100)
date(datetime)
I would like get record on this week, example if now 21.11.2013 i would like all rows on 18.11.2013 to 24.11.2013(on week)
Now I see next algorithm:
obtain weekday
calculate how many days ago was Monday
calculate the date Monday
calculate future date Sunday
make a request on date
Tell me please, is exist a shorter algorithm (preferably in the query MySQL)?
ADD Question is: Why this query select record on date 17.11.2013(Sunday) - 23.11.2013(Saturday) and how get records on date 18.11.2013(Monday) - 24.11.2013(Sunday) ?
query:
select * from temp
where yearweek(`date`) = yearweek(curdate())
Thanks!
Use YEARWEEK():
SELECT *
FROM your_table
WHERE YEARWEEK(`date`, 1) = YEARWEEK(CURDATE(), 1)
Use YEARWEEK. If you use WEEKOFYEAR you will get records of previous years also.
SELECT id, name, date
FROM table
WHERE YEARWEEK(date)=YEARWEEK(NOW());
For selecting records of day, week and month use this way:
function my_func($time, $your_date) {
if ($time == 'today') {
$timeSQL = ' Date($your_date)= CURDATE()';
}
if ($time == 'week') {
$timeSQL = ' YEARWEEK($your_date)= YEARWEEK(CURDATE())';
}
if ($time == 'month') {
$timeSQL = ' Year($your_date)=Year(CURDATE()) AND Month(`your_date`)= Month(CURDATE())';
}
$Sql = "SELECT * FROM your_table WHERE ".$timeSQL
return $Result = $this->db->query($Sql)->result_array();
}
You can do it by following method
SELECT DATE_FORMAT("2017-06-15", "%U");
Get number of week (From 00 to 53 )
Where (Sunday 1st day and Monday last day of week)
May be useful for you.
example:
SELECT DISTINCT DATE_FORMAT('dates', '%U') AS weekdays FROM table_name;
The short solution would be this:
SELECT * FROM my_table WHERE DATE_FORMAT("2021-08-19 15:40:33", "%U") = WEEK(CURDATE());

Compare dates from different years in mySQL

I'm getting a weird return when executing this query :
SELECT * FROM rrp
WHERE end > "2012-12-31"
nothing is returned, although I have one row on this table which "end" column is greater than "2012-12-31":
rrp
id_r | id__b | start | end | quantity
27 29 2012-01-01 2012-05-05 1
31 29 2012-11-01 2013-01-01 1
EDIT : startand endare date fields
EDIT : I used wrong database for my tests => wrong result
the issue was coming from Zend_Date when adding a day to a date:
$start = "2012-12-31";
$nStart = new Zend_Date($start, "YYYY-MM-dd");
$end = new Zend_Date($nStart);
$end->addDay(1);
When i echoed $end : echo $end->get("YYYY-MM-dd");
it outputs 2013-12-31
Most likely an issue with how the dates are formatted
This should help
http://dev.mysql.com/doc/refman/5.0/en/using-date.html
If end is a DATE column, it should work as expected:
SELECT
STR_TO_DATE('2013-01-01', '%Y-%m-%d') < "2012-12-31",
STR_TO_DATE('2012-05-05', '%Y-%m-%d') < "2012-12-31"
... returns 0, 1 in my box.
The only possible flaw I can think of is that your system's default date format is not %Y-%m-%d:
SELECT ##DATE_FORMAT
In that case, you need to specify a format every time:
SELECT *
FROM rrp
WHERE end > STR_TO_DATE('2012-12-31', '%Y-%m-%d')

Whats wrong with my MYSQL QUERY?

Can someone please tell me what is wrong with my query.
I am trying to fetch data fro my table based on the column called weekend, if weekend is set to "0" show from Sunday 6pm until Friday 9pm, then if weekend is set to "1" Show from Friday 9pm until Sunday 6pm.
SELECT *
FROM closures
WHERE closures.weekend = 0
OR WEEKDAY(NOW()) < 4
AND closures.weekend = 1
OR WEEKDAY(NOW()) > 4
OR (WEEKDAY(NOW())=4 AND HOUR(NOW())>21)
OR (WEEKDAY(NOW())=6 AND HOUR(NOW())<18)
It helps to phrase the question properly. What you should have said is "between 9pm Friday and 6pm Sunday I want to show the rows where closures.weekend = 1, otherwise show those where closures.weekend = 0".
Hence what you need to do is generate a value of 1 or 0 depending on whether it's the weekend or not, and then SELECT those rows where weekend has that value, i.e:
SELECT *
FROM
closures
WHERE
weekend = IF(
(WEEKDAY(NOW()) = 4 AND HOUR(NOW()) >= 21)
OR (WEEKDAY(NOW()) = 5)
OR (WEEKDAY(NOW()) = 6 AND HOUR(NOW()) < 18)
, 1, 0)
Weekend cant be both, 0 and 1
SELECT *
FROM
closures
WHERE
closures.weekend = 0
OR
(
WEEKDAY(NOW()) < 4
AND closures.weekend = 1
)
OR WEEKDAY(NOW()) > 4
OR
(WEEKDAY(NOW())=4 AND HOUR(NOW())>21)
OR
(WEEKDAY(NOW())=6 AND HOUR(NOW())<18)
My first guess is that the
SELECT field1, field2, ...
is missing ?