fetch rows from table based on from and to dates - mysql

I have a table as shown here:
In the table there are two columns named DateFrom and DateTo.
I want to fetch row data from or between these two dates. e.g. If I want to fetch data from 2018-12-27 to 2019-01-10 it should return the two rows with HPID 1 and 6 - as both row have or comes under the mentioned dates.
Now I don't know what the SQL query should be. I have tried BETWEEN but with no result.
Actually I am working on a small hotel management system and the table shows the cost of any hotel between certain dates. So when the user searches for hotels for date between two dates it should show costs which overlap those dates.
DateFrom and DateTo Are not datetime.

Stefan Taseki's answer is almost right but doesn't deal with overlaps correctly. Swap the start and end dates round in that query and it should do the job:
SELECT *
FROM [YourTable]
WHERE DateFrom <= '2019-01-10' AND DateTo >= '2018-12-27'
P.S. You should always store your dates in datetime columns. Dates are not text. You will have issues with a) sorting, b) comparisons, and c) presenting dates in different formats if you don't do this. The datetime data type exists for good reasons, you should use it. Consider changing your database now while you can.
P.P.S. Your data is also de-normalised. Country, City, HotelName, HotelCode and HotelStar should all be in a separate "hotel" table (and country and city each should be in different tables too), and then with a foreign key on Hotel ID only in this costs table. Otherwise you keep repeating data which should only be entered once. I suggest you learn about relational database design and normalisation, if you didn't realise this.

This should work:
SELECT *
FROM [YourTable]
WHERE DateFrom >= '2018-12-27' AND DateTo<= 2019-01-10

First of all make sure that your dates are in single quotes
'SELECT * FROM your_table WHERE DateFrom BETWEEN '2018-12-27' and '2019-01-10' OR DateTo BETWEEN '2018-12-27' and '2019-01-10';
Something that is not clear is what are you trying to achieve with this query.

Casting may be required, use below query
select *from your_table_name
where date(DateFrom) >= date('2018-11-27') AND date(DateTo) <= date('2019-01-10')

Related

Search a date between group of dates

My table name is client_details and my date field contain group of dates like
03/03/2015,04/13/2015,05/11/2015,06/08/2015,09/04/...
03/18/2015,04/28/2015,05/26/2015,06/23/2015,09/19/...
03/20/2015,04/30/2015,05/28/2015,06/25/2015,09/21/...
03/26/2015,05/06/2015,06/03/2015,07/01/2015,09/27/...
03/26/2015,05/06/2015,06/03/2015,07/01/2015,09/27/...
03/06/2015,04/16/2015,05/14/2015,06/11/2015,09/07/...
03/13/2015,04/23/2015,05/21/2015,06/18/2015,09/14/...
04/16/2015,05/27/2015,06/24/2015,07/22/2015,10/18/...
03/03/2015,04/13/2015,05/11/2015,06/08/2015,09/04/...
03/04/2015,04/14/2015,05/12/2015,06/09/2015,09/05/...
03/19/2015,04/29/2015,05/27/2015,06/24/2015,09/20/...
I want to search a date between '03/26/2015' and '05/12/2015'.How can i write the query?
You may try this:
SELECT * FROM client_details WHERE `DateField` BETWEEN '03/26/2015' AND '05/12/2015';
SQL Fiddle
EDIT:-
So your comments show that you are storing the dates by seperating them with comma. I would seriosuly discourage that practise and recommend you to change the design of your table. That is a poor way of storing the dates.
Reasons:
It will lead you to troubles everytime you want to use date functions.
It is not performance effective.
Alternate Solutions:
Change the design of your table.
Create a seperate table which stores the dates corresponding to a user_id and then join this table with your client_details table using the user_id and get the date which you want.

Two date columns, one date. How can I get the data?

I have the following problem:
In mysql I have a table which contains two date columns start_date and end_date. The date format is yyyy-mm-dd. What I am trying to do is to get all data from all the rows where a specific date, lets say '2012-03-05' mateches one of these date columns or are something in between.
How can I create a good sql-query that gets the data needed? I've checked on the between statement but I don't really know if that's the best way to go. I guess this is generally a simple task but I just can't figure a good query out.
Thanks.
SELECT * FROM table WHERE start_date <= '2012-02-29' AND end_date >= '2012-02-29';
Should do it.
This is a very common way to structure your tables with ranges of dates, especially in temporal database designs. It lets you perform range-based queries very efficiently, assuming that indexes on both columns exist. You query the data like this:
select *
from mytable t
where t.start_date <= #desired_date and t.endDate > #desired_date
#desired_date is the date for which you would like to query, e.g. '2012-03-05'.
Note the <= on one side and > on the other side, without =. This is done to ensure that the from-to ranges define non-overlapping intervals.
Not sure, try something like this:
SELECT
*
FROM
mytable
WHERE
'2012-03-05' BETWEEN start_date AND end_date
SELECT * FROM mytable
WHERE '2012-03-05' BETWEEN start_date AND end_date;

storing dates in mysql

Is it better to store dates in mysql in three columns or use just one column. Which one is faster. Also, if I just want to do inserts with todays date in format dd/mm/yy , how do I do that. and also how do I do selects with that. Also, lets say if I wanted to get results for all the wednesdays, how do I do that or lets say one date 25th of all the months and years, how do i do that.
Thanks People.
I am using PHP with Apache and Mysql.
What are the drawbacks of using the structure that I am proposing. I can easily get all the 25th by using the date table and I can get all the days using another column for days. How much difference would be there in the terms of speed between my proposed solution and using a DATE table?
You will want to use a proper column type, such as DATE, DATETIME, or TIMESTAMP, depending on your needs. They are built specifically to handle dates, and can more easily perform other functions (adding, comparing, etc.) that would be difficult to perform on 3 separate columns.
Read this for more info.
DAYOFWEEK(date) will give you a numeric representation for the day. In your case, 4 = Wednesday. DAYOFMONTH(date) will work for finding all 25th days of the month.
DAYNAME(date) will return the name of the weekday for date
Also, if I just want to do inserts with todays date in format dd/mm/yy ,how do I do that.
Well it depends on the format your date is passed in through your
form but you are going to want to store your date in YYYY-mm-dd format.
INSERT INTO my_table (timefieldname) VALUES ( '$date' );
and also how do I do selects with that.
SELECT timefieldname FROM my_table;
//or you can format the date - this will give you month/day/year 01/01/2012
SELECT DATE_FORMAT(timefieldname, '%m/%d/%Y') FROM my_table;
Also, lets say if I wanted to get results for all the wednesdays,
SELECT timefieldname FROM my_table WHERE DAYNAME(timefieldname) = 'Wednesday';
How do I do that or lets say one date 25th of all the months and years, how do i do that.
SELECT timefieldname FROM my_table WHERE DAY(timefieldname) = '25';
You can free up having to pass dates from your codebase and let mysql insert them for you, provided they are time stamps:
ALTER TABLE tablename ADD `timefieldname` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ;
It's not much of a speed boost, but it does reduce your need to code and validate variables passed to the database.

MySQL Select Dates in the Past: Problem with MAX and GROUP BY

So, the query I'm trying to make looks like this right now:
SELECT `jid`, MAX(`start`) as `start` FROM `dates` WHERE `start` < NOW() GROUP BY `jid`
The table dates basically holds a DATETIME value start associated with a job.
As you probably guessed, jid is the id of a job, stored in another table.
A job can have many dates
What I'm trying to accomplish is to find out what jobs have all their start dates in the past.
My thought was to select the highest values of the start dates, grouped by jid and if they were in the past, it would imply that all other dates associated with the same job are also in the past.
This query isn't working because it's checking for start dates in the past and then selecting the highest of those. This doesn't exclude the possibility of another date for the same job, lying in the future.
I have no idea how I could proceed now. Any help or clue is appreciated.
Cheers - Tom
You have to use HAVING :
SELECT jid, MAX(start) as start
FROM dates
GROUP BY jid
HAVING MAX(start) < NOW();
HAVING acts a bit like WHERE. It filters out the rows after they were selected. Usually (and actually, I can't think of any other case), you only use HAVING with aggregate functions.
(I hope you really inserted dates in the future in your table, though!)

MySQL multi table queries

I have a bunch of data ordered by date and each table holds only one month of data. (The reason for this is to cut down query time, I'm talking about millions of rows in each month table)
For ex.
data_01_2010 holds data from 2010-01-01 to 2010-01-31
data_02_2010 holds data from 2010-02-01 to 2010-02-28
Sometimes I have to query these tables according to a specific date range. Now if the range is across multiple months for ex. 2010-01-01 to 2010-02-28 then I need to query both tables.
Can this be achieved with a single query?
Like for example:
SELECT *
FROM data_01_2010, data_02_2010
WHERE date BETWEEN '2010-01-01' AND '2010-02-28'
The problem with the above query is that it says the column date is ambiguous which it is, because the column is present in both table. (tables have the same structure)
So is this achievable with a single query or do I have to query it for each table separately?
This is a perfect example of why partitioning is so powerful. Partitioning allows you to logically store all of your records in the same table without sacrificing query performance.
In this example, you would have one table called data (hopefully you would name it better than this) and range partition it based on the value of the date column (again hopefully you would name this column better). This means that you could meet your requirement by a simple select:
SELECT * FROM data WHERE date BETWEEN '2010-01-01' AND '2010-02-28';
Under the covers, the database will only access the partitions required based on the where clause.
Reference:
http://dev.mysql.com/doc/refman/5.5/en/partitioning.html
If you do the logic elsewhere to figure out what tables you need to query, and each month has the same schema, you could just union the tables:
SELECT *
FROM data_01_2010
WHERE date BETWEEN '2010-01-01' AND '2010-02-28'
UNION ALL
SELECT *
FROM data_02_2010
WHERE date BETWEEN '2010-01-01' AND '2010-02-28'
But if you need the query to calculate which tables to union, you are venturing into realm of stored procedures.