MySQL - Returning rows between two dates/times - php

The MySQL table I'm working with has date and time as separate columns. Dates are in the format of "y-m-d" and "hh:mm:ss" for time. How exactly do I search for the rows in between two times if they are in different days? (For example the rows between 2013-01-15 12:00:00 and 2013-01-17 17:00:00)
Right now, I'm using a bad workaround assuming that the time difference will be at most one day but that will not always be the case. There probably is an easy way of accomplishing this but I just can't figure out what. Thanks!

concatenate the fields using CONCAT
SELECT *
FROM tableName
WHERE CONCAT(dateCol, ' ', timeColumn) BETWEEN
'2013-01-15 12:00:00' AND '2013-01-17 17:00:00'
but I recommend that you (if possible) to alter the table by combining the two columns with datatype DateTime so you can take advantage of the indexes. The query above which uses CONCAT requires full table scan which is very poor in performance for large databases.

JW.'s answer can be sped up by first using the index to narrow down the search space and then trimming the results down to the correct set.
select * from births
where date between '2013-01-15' and '2013-01-17' -- use index
and concat(date, ' ', time) between '2013-01-15 12:00:00' and '2013-01-17 17:00:00'
;
See this SQL Fiddle for more details.

Related

SQL Subtract two rows from each other in same column to get a result

I am running many energy readers which collects data with intervals of 5min. To get power used between two time stamps, I need to subtract older data from the newer data.
I am new to SQl, so I would like to ask what SQL syntax do I need to use to get a total sum between two Values.
Database Structure example:
Thank you very much.
You would typically use window function lead() or lag() - if your database supports that.
The following query puts on each row the difference with the previous value of the same equipment:
select
t.*,
t_energy_a - lag(t_energy_a) over(partition by meter_id order by dod) diff
from mytable t

Mysql search between two date with time

how to search between two date , when date format in database like :
2015-10-10 02:23:41 am
i just want to search between two date with format :
2015-10-10
without
02:23:41 am
any ideas please ?
Your question isn't completely clear. But, I guess you hope to find all the rows in your table where Date occurs on or after midnight on 2015-08-05 and before midnight on 2015-09-11 (the day after the end of the range you gave in your question.
Those two search criteria will find all the rows with Date values in the range you specified. (I'm ignoring the 02 at the end of 2015-09-10 02 in your question because I can't guess what it means, if anything.)
Try this query:
SELECT *
FROM table
WHERE `Date` >= '2015-08-05'
AND `Date` < '2015-09-10' + INTERVAL 1 DAY
This has the benefit that it can exploit an index on the Date column if you have one, so it can be fast.
You could write
SELECT *
FROM table /* slow! */
WHERE DATE(`Date`) BETWEEN '2015-08-05' AND '2015-09-10'
That's slightly easier to read, but the WHERE condition isn't sargable, so the query will be slower.
Notice that the beginning of the range uses >= -- on or after midnight, and the end of the range uses < -- before midnight.
Pro tip: Avoid the use of reserved words like DATE for column names. If you make mistakes writing your queries, their presence can really confuse MySQL, not to mention you, and slow you down.
May I suggest:
select * from table where cast(date as date) between '2015-08-05' and '2015-09-10'
When your where clause is based on a timestamp, but you're using date as the parameters for your between, it excludes anything that happens on the second date unless it happened precisely at midnight.
When using the end date for the range, include the time of the end of the day:
SELECT *
FROM YourTable
WHERE date BETWEEN '2015-08-05' AND '2015-09-10 23:59:59'

Get all rows from a specific month and year

I have a PHP scirpt that is always querying all the data from a database table and it's getting pretty slow. I really just need the data of a specific month and year.
Is there a simple way to get only those entries? For example, everything from February 2013?
The column that stores the dates in my table is of type datetime, if that applies to the solution.
You can add that condition in the WHERE clause of your select statement. I would recommend using BETWEEN operand for two dates:
SELECT myColumns
FROM myTable
WHERE dateColumn BETWEEN '2013-02-01' AND '2013-02-28';
If you mean to say you want everything beginning with February 2013, you can do so using the greater than or equal to operator:
SELECT myColumns
FROM myTable
WHERE dateColumn >= '2013-02-01';
EDIT
While the above are my preferred methods, I would like to add for completeness that MySQL also offers functions for grabbing specific parts of a date. If you wanted to create a paramaterized query where you could pass in the month and year as integers (instead of a start and end date) you could adjust your query like this:
SELECT myColumns
FROM myTable
WHERE MONTH(dateColumn) = 2 AND YEAR(dateColumn) = 2013;
Here is a whole bunch of helpful date and time functions.
You should index the datetime field for added efficiency and then use Between syntax in your sql. This will allow the mysql engine to remove all records that you are not interested in from the returned data set.

MySQL select all dates between two dates

I have a table called schedules which contains columns day, month, year, etc. What I need is to select records between the $datefrom and $dateto. Here is my code that does not work :(
SELECT * FROM schedules WHERE CONCAT(year, month, day) BETWEEN $datefrom AND $dateto
Im not sure if this is correct. Please help.
Like showdev already said in a comment, you have to cast the string that is returned from CONCAT() function to date. But consider, that no index can be used on this.
I'd suggest you create an additional column in your table with the full date. I don't know if you separated the date into 3 columns out of performance reasons, but have a try, if only one column is enough for you. Usually it's fast enough (when indexed).
If you don't want to do that and want to use indexes (if they exist at all on those 3 columns) you would have to write the query like this:
SELECT * FROM schedules WHERE
`year` BETWEEN YEAR($datefrom) AND YEAR($dateto)
AND `month` BETWEEN MONTH($datefrom) AND MONTH($dateto)
AND `day` BETWEEN DAY($datefrom) AND DAY($dateto)

query mysql: Select from timestamp

I want to SELECT all the rows from the table that correspond to a specific date.
I have the timestamp stored in the pattern 2010-08-18 04:43:00.
How can I query the table if I want to select all the rows that fall within a day's time?
One way I can think of is get the day's timestamp, convert it into Unix timestamp and then query the table. But that sounds like a lot of work. Is there any easier alternative?
Thanks a lot in advance.
SELECT *
FROM `table_name`
WHERE `date_column` LIKE '2010-08-17 %';
Or:
SELECT *
FROM `table_name`
WHERE DAY( `date_column` ) = 17
AND MONTH( `date_column` ) = 08
AND YEAR( `date_column` ) = 2010
LIMIT 0 , 30
Reference: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
The approach outlined by Michael works, but is string-based and as such not as efficient as an integer-based search.
I don't really see a problem in creating two UNIX timestamps, one for 00:00:00 and one for 23:59:59, and checking to see if you fall within that time. (Be sure to actually calculate these two separate values to make sure you account for daylight savings time).
You can even use MySQL to get those values if you really don't want to do it yourself (SELECT UNIX_TIMESTAMP("$Timestamp 00:00:00"), UNIX_TIMESTAMP("$Timestamp 23:59:59")), and then use those two values.
If you have a small dataset, Michael's approach above is fine.
Quite simply:
SELECT *
FROM `table_name`
WHERE DATE(`date_column`) = '2010-08-17';
Note that it will only be efficient if your date_column is of type TIMESTAMP or DATETIME.
Edit:
Since Martin raised a point related to performance, you might want to try this instead if speed is an issue (on a huge data set). BETWEEN will make use of any available indexes.
SELECT *
FROM `table_name`
WHERE `date_column` BETWEEN '2010-08-17 00:00:00' AND '2010-08-17 23:59:59';

Categories