I am working with a MySQL table which has entries like the following for the timestamp 2016-12-28T21:42:53.000-04:00 provided as a CHAR field.
One of the tasks I need to do is to retrieve all the records for the current date.
Right now what I am doing is getting the current date into a php variable ($date) in the same format as the one in the MySQL table. ie 2016-12-28 and use a LIKE statement to find all the records matching it.
The problem comes when I need to find all the records for the last 10 days for example.
Is there anyway to convert that field into a valid date one which I can use for more complex queries like find the last 10 days, etc?
Any tip in the right direction will be appreciated,
Thanks
You can just convert it to a date. One method is:
select date(left(field, 10))
I should add that this will work just as well in a where clause:
where date(left(field, 10)) >= date_sub(curdate(), interval 10 day)
But . . . using functions on columns precludes the use of indexes. In this case, you have a good date format, so you could do:
where field >= date_format(date_sub(curdate(), interval 10 day), '%Y-%m-%d')
This version can take advantage of an index on field.
All that said . . . storing fields using the proper type is highly recommended.
Related
I have a table called reports in MySQL(MariaDB) . There is a one(out of 5) column named logdate which is is of type datetime .columns stores the the date and time (in 24hr format) .
for ex here is sample value from that column
2021-04-10 09:35:00
I have to find all reports between a given date and time .
I get 4 variables from form data in PHP
$fromdate= $_POST['fromdate'];
$todate= $_POST['todate'];
$fromtime= $_POST['fromtime'];
$totime= $_POST['totime'];
$fromtime and $totime are just integers with value from 0-23 for hours.
For example the condition may be like get all data between 4th April 2021
from 5 o'clock To 8 April 2021 18 o'clock
i.e. From 2021-04-04 03:00:00 to 2021-04-08 18:00:00. There will be never condition on minutes and seconds .
My question is how to construct a datetime in PHP compatible with MySQL types so I can have good(efficient, there are millions of records in table ) search speed?
for ex
$select = "select * from reports where logdate between ? and ? ";
P.S: I tried saving date and time as integer as unixtime stamp. But when i convert from and to date received using strttotime() I facing time format issue due to bug in my code which so can use datetime only.
If you have any suggestion to improve efficiency of DB please suggest.Thanks
Hi this link may be of help in optimizing date comparison
MySQL SELECT WHERE datetime matches day (and not necessarily time)
This one below, will help you in formatting your strtotime() by using strptime()
https://www.php.net/manual/en/function.strptime.php
Also check your spelling or typo; you wrote "strttotime()" instead of "strtotime()" yours has an extra 't' in str"tto"time, it should be str"to"time, though without the double qoutes
Though I can't say for sure this is the most effective way but you can use hour(logdate) to compare with $fromdate and $todate
$select = "select * from reports where hour(logdate) between ? and ? ";
But it will only compare hour part. Please mention how you are getting date part to compare?
It is not a good idea to make a calculation on a field in the WHERE CLAUSE. In this case MySQL / MariaDB must calculate the value from this field to comapare it to see
if this ROW has this condition. So MySQL must read the whole table FULL TABLE SCAN and CANT use any INDEX.
A better way to do this is to store the calculation on fix site. Then MySQL calculated it only one time and can use a Index ( if there one) .
you can easy use a query like this:
$select = "SELECT * FROM reports where logdate between date(?) + INTERVAL ? HOUR AND date(?) + INTERVAL ? HOUR ";
to test see:
SELECT date('2021-04-05') + INTERVAL 16 HOUR;
result:
2021-04-05 16:00:00
Here is what is working for me after using Bernds solution .
I constructing datetime string in php
$fromstr ="$fromdate"." "."$fromtime".":00:00";
$tostr="$todate"." "."$totime".":00:00";
here is my query looks like for date of 7th April to 10th April
$ select = "SELECT * FROM reports where logdate >= '$fromstr' and logdate <= '$tostr' order by logdate";
after echoing it
"SELECT * FROM reports where logdate >= '2021-04-07 3:00:00' and logdate <= '2021-04-10 5:00:00' order by logdate";```
However I am not sure if can use index for logdate column and utilize it with above query.
I need to select data from mysql for last 7 days. I have field named 'date' and which have values in mm.dd.yy format.
So i tried to find special mysql request to do that, but its not work with my field, i gues that beacause date in wrong format.
How i can do that from php (use some variable to get mysql entries), or with custom select query ?
You can use STR_TO_DATE() to convert your idiosyncratic date format to a standard DATE value. An expression like this will do the trick
STR_TO_DATE('07.17.97', '%m.%d.%y')
Then you can say
WHERE STR_TO_DATE(`date`, '%m.%d.%y') >= CURDATE() - INTERVAL 7 DAY
in your query to filter items with date values starting a week ago.
But, if you have a lot of rows to filter you will have poor performance: this kind of WHERE clause is not sargable.
First read your table and change the date format
$new_date_format = date('Ymd',mktime(0,0,0,substr($date,0,2),substr($date,3,2),substr($date,6,2)));
After that you can make comparisions
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.
I've got a MySQL table of stays, where each stay is defined with a from_date and to_date column. And I want to find all stays in range defined by user. For example, given that there is a stay from 01.01.2015 to 01.03.2015 I want this entry to be included in reports from 01.01.2015 to 31.01.2015 but also from 01.02.2015 to 28.02.2015 and in 01.03.2015 to 31.03.2015.
I've got everything stored as timestamps (in seconds).
Could somebody, please, give an example how to achieve this?
Abstract MySQL query:
select *
from table_of_stays
where ( date($stay_from_date)
between date($report-start-date) and date($report-end-date))
and (date($stay_to_date) < date($report-end-date))
First part of the match: stay_from_date must be in the range of the report.
Second part of the match: stay_to_date must be before the end date of the report.
All $variables are mysql DATETIME types = 2011-09-21 08:21:22, see
MySQL reference: http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_date
You can use BETWEEN to select a date between two values, and combine it with an OR so you select either the from date or the to date:
SELECT * FROM your_table
WHERE (from_date BETWEEN 'date_1' AND 'date_2')
OR (to_date BETWEEN 'date_1' AND 'date_2');
See this related answer for more information, and keep in mind you will need to convert the user input dates to timestamps, or convert your timestamps to dates for the comparison.
Ok, thanks to the other answers I got the best results with
(stay_range_start<=selected_range_end) && (stay_range_end>=selected_range_start) in mysql:
SELECT * FROM stays
WHERE `t0`.`from_date` <= $to_date
AND `t0`.`to_date` >= $from_date
In my project , I am generating and storing the Bill (invoice).
The date of Bill is coming to the textbox from the javascript date picker(small pop-up calender) before saving.
The format of the date is : DD-MON-YYYY (18-JUN-2013).
I am using 'Text' data type for storing dates in MySql table.
I have done selecting of records(Previous Bills) from the table by given single date like. . .
$result = mysql_query("SELECT * FROM outward WHERE date='".$date."' ORDER BY billNo");
Now, what i want to do is:
To select records (Bills) between two dates.....
My exact Question is:
Is it possible to query mysql database with this settings or I have to make some changes to select records between 2 dates efficiently ?
How can i achieve this ?
P.s. - Is it effective to use
1. "SELECT * FROM outward WHERE date BETWEEN '" . $from_date . "' AND '" . $to_date . "' ORDER by id DESC"
Or
2. SELECT * FROM outward WHERE date > "15-JUN-2013" and date < "18-JUN-2013"
You could do it in a pure SQL way, but you are going to have to do a full table scan for each query.
select the_dates,
STR_TO_DATE(the_dates, '%d-%M-%Y') as converted
from testing
where STR_TO_DATE(the_dates, '%d-%M-%Y') between '2013-06-20' and '2013-06-23'
Link to SQLFiddle
You should use strtotime PHP function to convert string date to UNIX timestamp format and change MySQL data type for date field to TIMESTAMP.
Than you can do effective queries with > and <.
If it's a DATE column, you can get all dates between 15 June 2013 and 18 June 2013 (inclusive) using this:
WHERE date BETWEEN '2013-06-15' AND '2013-06-18'
If it's a DATETIME column, do this instead:
WHERE date >= '2013-06-15' AND date < '2013-06-19'
If the date column is indexed, this approach will make sure the indexes are available for optimization. If it isn't indexed, the approach is just as fast as the many other ways you can do this.
Addendum: Just saw the "storing as text" amidst all the other shouted info. Note that this answer applies only if the type is DATE or DATETIME. I'll leave it up because the best answer is to change the column's data type and then use this or one of the other suggested options.
I am using 'Text' data type for storing dates in MySql table.
That's a problem. You should store dates as date or datetime data type in MySQL. If you don't care about the time part, date should be sufficient.
If you change your data type to date, then doing:
select x,y,z from table a where a.datecolumn between #startdate and #enddate
Should work fine.
If you use a text data type, you would have to cast the column to a date column and then apply your date selection range which is going to be slower due to the cast.
Always store data in the data type that matches its kind. If a date then a date column, if it's text then text or varchar, etc. The presentation layer of your app can worry about the format in which this data is presented to the user.
You said you were using a TEXT column to store the dates. That's an extremely bad idea. If you switch to a DATE or a DATETIME, then this becomes trivial.
Since you are storing it as text but you want SQL to parse it as a DATE SQL doesn't understand in the first place.
In your example SQL will use TEXT comparison rules. So 15-April < 15-Mar > 15-DEC
If you are storing dates in an SQL database you should be storing it as a Date and not as TEXT.