mysql: just select something happen in the weekend - mysql

I have a table, store all user created events, and with a field "start_time" and a "end_time"
How to select all events just happens in weekend?

Use DAYOFWEEK():
Returns the weekday index for date (1 = Sunday, 2 = Monday, …, 7 = Saturday). These index values correspond to the ODBC standard.
Something like
SELECT * FROM events WHERE DAYOFWEEK(start_time) = 7
OR DAYOFWEEK(start_time) = 1
...

I would suggest using the BETWEEN operator. Something like:
SELECT ... FROM EVENTS WHERE
START_TIME BETWEEN :weekend_start AND :weekend_end
OR END_TIME BETWEEN :weekend_start AND :weekend_end
(where you then figure out the start and end times for the weekend in question, and bind them in appropriately)
The above will find anything that at least overlaps with the weekend. If the event must be entirely contained with the weekend (i.e. can't start before and can't start after) then just change the OR to an AND.

Related

Stored procedure for update date range and price in mysql

I have a table lets say:
tblHotel
id
start_date
end_date
rate
Now I want to write procedure for update records for date range, say for example I have data:
id start_date end_date rate
1 2016/01/01 2016/01/10 10
2 2016/01/11 2016/01/20 50
Now if a new date range and rate comes from supplier I want to update tables record like new range is.
start_date end_date rate
2016/01/05 2016/01/12 100
Now updated records should be like this:
id start_date end_date rate
1 2016/01/01 2016/01/04 10
2 2016/01/05 2016/01/12 100
3 2016/01/13 2016/01/20 50
I'm not going to write the code for you, but handling overlapping time frame is tricky. You need to handle this as different cases:
If nothing overlaps, then this is simple:
insert into tbl_Hotel(start_date, end_date, rate)
select $start_date, $end_date, $rate
from dual
where not exists (select 1
from tbl_Hotel h
where h.start_date <= $end_date and h.end_date >= $start_date
);
Easy . . . And in the stored procedure the where can be handled using if logic.
Then the hard part. There are four types of overlaps:
-------hhhhhhhhhhh--------
a) ---------xxxxx------------
b) -----xxxxxx---------------
c) ----------xxxxxx----------
d) --xxxxxxxxxxxxxxxxxxxxxx--
And, then it gets a bit more complicated because a new rate period could overlap with more than one existing period.
Arrrg! How do you approach this? Carefully and with test cases. You might even want to use a cursor (although there are non-cursor-based methods as well).
The idea is to pull out one overlapping existing period. Then, for that period handle the logic:
a) The existing period needs to be split into two parts (with appropriate end dates. Then the new reservation can just be added.
b) The start date of the existing period has to change to one more than the end date of the new one. Then the new one inserted.
c) The end date of the existing period has to change to one less than the start date of the new one. Then the new one inserted.
d) The old record is removed and the new one inserted.
As I say, good tests for your stored procedure are important, so you can actually check that it works.

Return rows for next month, MYSQL

I have a mysql table which stores users' availability, stored in 'start' and 'end' columns as date fields.
I have a form where other users can search through the 'availabilty' with various periods like, today, tomorrow and next week . I'm trying to figure out how to construct the query to get all the rows for users who are available 'next month'.
The 'start' values maybe from today and the 'end' value might might be three months away but if next month falls between 'start' and 'end' then I would want that row returned.
The nearest I can get is with the query below but that just returns rows where 'start' falls within next month. Many thanks,
sql= "SELECT * FROM mytable WHERE start BETWEEN DATE_SUB(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)),INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)))-1 DAY) AND LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH))";
As you are interested in anything that happens in the full month following the current date you could try something like this:
SELECT * FROM mytable WHERE
FLOOR(start/100000000)<=FLOOR(NOW()/100000000)+1 AND
FLOOR( end/100000000)>=FLOOR(NOW()/100000000)+1
This query make use of the fact that datetime values are stored in MySql internally as a number like
SELECT now()+0
--> 20150906130640
where the digits 09 refer to the current month. FLOOR(NOW()/100000000) filters out the first digits of the number (in this case:201509). The WHERE conditions now simply test whether the start date is anywhere before the end of the next month and the end date is at least in or after the period of the next month.
(In my version I purposely left out the condition that start needs to be "after today", since a period that has started earlier seems in my eyes still applicable for your described purpose. If, however, you wanted that condition included too you could simply add an AND start > now() at the end of your WHERE clause.)
Edit
As your SQLfiddle is set-up with a date instead of a (as I was assuming) datetime column your dates will be represented differently in mumeric format like 20150907 and a simple division by 100 will now get you the desired month-number for comparison (201509):
SELECT * FROM mytable WHERE
FLOOR(start/100)<=FLOOR(NOW()/100000000)+1 AND
FLOOR( end/100)>=FLOOR(NOW()/100000000)+1
The number returned by NOW() is still a 14-digit figure and needs to be divided by 100000000. See your updated fiddle here: SQLfiddle
I also added another record ('Charlie') which does not fulfill your requirements.
Update
To better accommodate change-of-year scenarios I updated my SqlFiddle. The where clause is now based on 12*YEAR(..)+MONTH(..) type functions.

mysql get data from a specific week [duplicate]

I am having a table as follows in MYSQL:
proj_id|hoursWorked|Date.
The date field is of type Date; I want to retrieve all the entries from a table depending on a given week number for the project in my java based web application. Please help me to achieve this.
I am unable to write a single query that will allow me to do so.
Do not use something like WHERE WEEK(column)=something - this is a performance killer: It will calculate the week number on all rows, even if they don't match. In addition to that it will make it impossible to use an index ont this column.
Instead calculate an absolute begin and end date or point in time, depending on your data type, then use BETWEEN. This will do no calculations on non-matching rows and allow the use of an index.
Rule of thumb: If you have the choice between a calculation on a constant and on a field, use the former.
use MySQL WEEK() function.
SELECT WEEK(dateColumn)
FROM...
WHERE WEEK(dateColumn) = 1
WEEK()
from MySQL Docs
This function returns the week number for date. The two-argument form
of WEEK() enables you to specify whether the week starts on Sunday or
Monday and whether the return value should be in the range from 0 to
53 or from 1 to 53.
Use WEEK
select * from your_table
where week(`Date`) = week('2012-12-01')
If you want to get only records from the current week you can do
select * from your_table
where week(`Date`) = week(curdate())

MySQL query to select events between start/end date

I have a MySQL table named 'events' that contains event data. The important columns are 'start' and 'end' which contain string (YYYY-MM-DD) to represent when the events starts and ends.
I want to get the records for all the active events in a time period.
Events:
------------------------------
ID | START | END |
------------------------------
1 | 2013-06-14 | 2013-06-14 |
2 | 2013-06-15 | 2013-08-21 |
3 | 2013-06-22 | 2013-06-25 |
4 | 2013-07-01 | 2013-07-10 |
5 | 2013-07-30 | 2013-07-31 |
------------------------------
Request/search:
Example: All events between 2013-06-13 and 2013-07-22 : #1, #3, #4
SELECT id FROM events WHERE start BETWEEN '2013-06-13' AND '2013-07-22' : #1, #2, #3, #4
SELECT id FROM events WHERE end BETWEEN '2013-06-13' AND '2013-07-22' : #1, #3, #4
====> intersect : #1, #3, #4
Example: All events between 2013-06-14 and 2013-06-14 :
SELECT id FROM events WHERE start BETWEEN '2013-06-14' AND '2013-06-14' : #1
SELECT id FROM events WHERE end BETWEEN '2013-06-14' AND '2013-06-14' : #1
====> intersect : #1
I tried many queries still I fail to get the exact SQL query.
Don't you know how to do that? Any suggestions?
Thanks!
If I understood correctly you are trying to use a single query, i think you can just merge your date search toghter in WHERE clauses
SELECT id
FROM events
WHERE start BETWEEN '2013-06-13' AND '2013-07-22'
AND end BETWEEN '2013-06-13' AND '2013-07-22'
or even more simply you can just use both column to set search time filter
SELECT id
FROM events
WHERE start >= '2013-07-22' AND end <= '2013-06-13'
You need the events that start and end within the scope. But that's not all: you also want the events that start within the scope and the events that end within the scope. But then you're still not there because you also want the events that start before the scope and end after the scope.
Simplified:
events with a start date in the scope
events with an end date in the scope
events with the scope startdate between the startdate and enddate
Because point 2 results in records that also meet the query in point 3 we will only need points 1 and 3
So the SQL becomes:
SELECT * FROM events
WHERE start BETWEEN '2014-09-01' AND '2014-10-13'
OR '2014-09-01' BETWEEN start AND end
Here lot of good answer but i think this will help someone
select id from campaign where ( NOW() BETWEEN start_date AND end_date)
SELECT id
FROM events
WHERE start <= '2013-07-22'
AND end >= '2013-06-13';
Or use MIN() and MAX() if you don't know the precedence.
SELECT *
FROM events
WHERE start <= '2013-07-22' OR end >= '2013-06-13'
SELECT *
FROM events
WHERE endDate >= #startDate AND startDate <= #endDate
For explanation refer to this diagram:
Suppose sample data is [startDate: 2020-10-01, endDate: 2020-20-01]
The user provides #startDate and #endDate to search
For overlap there are 4 scenarios and 1 variation (red/maroon lines)
For no overlap there are just 2 scenarios (green lines)
So, in order to get overlapping dates by providing start and end date, endDate must be greater than #startDate and startDate must be less than #endDate.
EDIT: I've squeezed the filter a lot. I couldn't wrap my head around it before how to make sure something really fit within the time period. It's this: Start date BEFORE the END of the time period, and End date AFTER the BEGINNING of the time period
With the help of someone in my office I think we've figured out how to include everyone in the filter.
There are 5 scenarios where a student would be deemed active during the time period in question:
1) Student started and ended during the time period.
2) Student started before and ended during the time period.
3) Student started before and ended after the time period.
4) Student started during the time period and ended after the time period.
5) Student started during the time period and is still active (Doesn't have an end date yet)
Given these criteria, we can actually condense the statements into a few groups because a student can only end between the period dates, after the period date, or they don't have an end date:
1) Student ends during the time period AND [Student starts before OR during]
2) Student ends after the time period AND [Student starts before OR during]
3) Student hasn't finished yet AND [Student starts before OR during]
(
(
student_programs.END_DATE >= '07/01/2017 00:0:0'
OR
student_programs.END_DATE Is Null
)
AND
student_programs.START_DATE <= '06/30/2018 23:59:59'
)
I think this finally covers all the bases and includes all scenarios where a student, or event, or anything is active during a time period when you only have start date and end date. Please, do not hesitate to tell me that I am missing something. I want this to be perfect so others can use this, as I don't believe the other answers have gotten everything right yet.
try this
SELECT id FROM events WHERE start BETWEEN '2013-06-13' AND '2013-07-22'
AND end BETWEEN '2013-06-13' AND '2013-07-22'
DEMO HERE
output :
ID
1
3
4
If you would like to use INTERSECT option, the SQL is as follows
(SELECT id FROM events WHERE start BETWEEN '2013-06-13' AND '2013-07-22')
INTERSECT
(SELECT id FROM events WHERE end BETWEEN '2013-06-13' AND '2013-07-22')
In PHP and phpMyAdmin
$tb = tableDataName; //Table name
$now = date('Y-m-d'); //Current date
//start and end is the fields of tabla with date format value (yyyy-m-d)
$query = "SELECT * FROM $tb WHERE start <= '".$now."' AND end >= '".$now."'";
If anyone is searching for a situation when the current date is residing between two periods (start/end date) in Microsoft SQL, please find below
select id from campaign where (getdate() BETWEEN start_date AND end_date)

SQL Statement Database

I have a Mysql Table that holds dates that are booked (for certain holiday properties).
Example...
Table "listing_availability"
Rows...
availability_date (this shows the date format 2013-04-20 etc)
availability_bookable (This can be yes/no. "Yes" = the booking changeover day and it is "available". "No" means the property is booked for those dates)
All the other dates in the year (apart from the ones with "No") are available to be booked. These dates are not in the database, only the booked dates.
My question is...
I have to make a SQL Statement that first calls the Get Date Function (not sure if this is correct terminology)
Then removes the dates from "availability_date" WHERE "availability_bookable" = "No"
This will give me the dates that are available for bookings, for the year, for a property.
Can anyone help?
Regards M
Seems like you've almost written the query.
SELECT availability_date FROM listing_availability
WHERE availability_bookable <> 'NO'
AND availability_date >= CURDATE()
AND YEAR(CURDATE()) = YEAR(availability_date)
I think I understand, and you'll obviously confirm. Your "availability_booking" has some records in it, but not every single day of the year, only those that may have had something, and not all are committed, some could have yes, some no.
So, you want to simulate All dates within a given date range... Say April 1 - July 1 as someone is looking to book a party within that time period. Instead of pre-filling your production table, you can't say that April 27th is open and available... since no such record exists.
To SIMULATE a calendar of days for a date range, you can do it using MySQL variables and join to "any" table in your database provided it has enough records to SIMULATE the date range you want...
select
#myDate := DATE_ADD( #myDate, INTERVAL 1 DAY ) as DatesForAvailabilityCheck
from
( select #myDate := '2013-03-31' ) as SQLVars,
AnyTableThatHasEnoughRows
limit
120;
This will just give you a list of dates starting with April 1, 2013 (the original #myDate is 1 day before the start date since the field selection adds 1 day to it to get to April 1, then continues... for a limit of 120 days (or whatever you are looking for range based -- 30days, 60, 90, 22, whatever). The "AnyTableThatHasEnoughRows" could actually be your "availability_booking" table, but we are just using it as a table with rows, no join or where condition, just enough to get ... 120 records.
Now, we can use this to join to whatever table you want and apply your condition. You just created a full calendar of days to compare against. Your final query may be different, but this should get it most of the way for you.
select
JustDates.DatesForAvailabilityCheck,
from
( select
#myDate := DATE_ADD( #myDate, INTERVAL 1 DAY ) as DatesForAvailabilityCheck
from
( select #myDate := '2013-03-31' ) as SQLVars,
listing_availability
limit
120 ) JustDates
LEFT JOIN availability_bookable
on JustDates.DatesForAvailabilityCheck = availability_bookable.availability_date
where
availability_bookable.availability_date IS NULL
OR availability_bookable.availability_bookable = "Yes"
So the above uses the sample calendar and looks to the availability. If no such matching date exists (via the IS NULL), then you want it meaning there is no conflict. However, if there IS a record in the table, you only want those where YES, you CAN book it, the entry on file might not be committed and CAN be in your result query of available dates.