mysql and date comparison with date function and without - mysql

I notice a strange behavior for me when using date() and without:
when I use
SELECT * FROM `mytable` WHERE date(date_add) >= '2017-08-01' and date(date_add) <= '2017-08-31'
I get all dates records within the given date range but if do:
SELECT * FROM `mytable` WHERE date_add >= '2017-08-01' and date_add <= '2017-08-31'
I don't get the rows from the last day 31, why? (the date_add field is datetime type)
EDIT:
How should I code date range correctly? Because what I understand so far is that if I don't use full time like YYYY-MM-DD HH-MM-SS I should always compare with DATE() to avoid missing results from the last day.

That's because date_add is a DATETIME field. If the time for the date 2017-08-31 is something like 08:15:00 or 13:21:00 in your table, your date is "bigger" than just 2017-08-31 00:00:00. Your comparison would just return data for the 2017-08-31 having the time 00:00:00.

Because without the date() transformation your comparison imply the values '2017-08-01 00:00:00' and '2017-08-01 00:00:00'

Related

query for date range '01-01-2019' and '02-02-2019' is not working

I have a query with date range like between '01-01-2019' and '03-02-2019' and it is working while I change day(02) of date range like '01-01-2019' and '02-02-2019' then Query is not working.
I have a query with date range from '01-01-2019' and To : '03-02-2019' like
SELECT * FROM `customer_info` WHERE `rec_date` between '01-01-2019' and '03-02-2019'
so it is working but when I change the day of date range like from '01-01-2019' and To : '02-02-2019' and query is
SELECT * FROM `customer_info` WHERE `rec_date` between '01-01-2019' and '02-02-2019'
But query is not working.
I want from this query that it should fetch records after changing day of date range of TO : '02-02-2019'.Please tell me solution why it is not fetching records.
With Only Date:
MySQL date format is this : YYYY-MM-DD. In a simple way it can be queried as
select * from customer_info where rec_date between '2019-01-01' and '2019-02-02'
OR
select * from customer_info where rec_date between >= '2019-01-01' and '2019-02-02'
With Date & Time:
Just use the format which MySQL handles dates YYYY-MM-DD HH:MM:SS and have the query as
select * from customer_info where rec_date >= '2019-01-01' and rec_date <= '2019-02-02'
Especially since MySQL now supports sub-second time precision. Using 23:59:59 is one full second short of the end of a day. where rec_date >= '2019-01-01' and rec_date <= '2019-02-02' is the most precise way to define a date range and will work for any level of time precision from date to sub-second units.
OR
Simple as that.
select * from customer_info where rec_date between '2019-01-01 00:00:00' and '2019-02-02 23:59:00'
That rec_date is probably a VARCHAR or CHAR type instead of a DATE type.
Then it should be transformed to a DATE type before getting a range from that.
Otherwise the BETWEEN will compare the strings alphabetically.
And when you then query a date range, use the 'YYYY-MM-DD' format for date constants.
That won't lead to a confusion with the months and days.
(Is '01-04-2019' the 1st of April, or the 4th of January?)
SELECT *
FROM `customer_info`
WHERE STR_TO_DATE(rec_date,'%m-%d-%Y') BETWEEN '2019-01-01' and '2019-03-02'

MySQL searching timestamp columns by date only

I am building out a query to search a table by a timestamp column value. An example of the format I am passing to the api is 2018-10-10. The user has the ability to select a date range. Often times the date range start date is 2018-10-10 and end date is the same day, 2018-10-10. The below doesn't seem to do the trick. What is the simplest way to accomplish this without having to specify the time? Obviously, I'd like to query for the entire day of 2018-10-10 from start to end of day.
SELECT
count(*)
FROM
contact
WHERE
created_at >= '2018-10-10'
AND created_at <= '2018-10-10';
The problem here is that Timestamp datatype will have HH:MM:SS (time) values also. While comparing a datetime with date, MySQL would automatically assume 00:00:00 as HH:MM:SS for the date value.
So, 2018-10-10 12:23:22 will not match the following condition: created_at <= '2018-10-10'; since it would be treated as: 2018-10-10 12:23:22 <= '2018-10-10 00:00:00, which is false
To handle this, you can add one day to the date (date_to in the filter), and use < operator for range checking.
SELECT
count(*)
FROM
contact
WHERE
created_at >= '2018-10-10'
AND created_at < ('2018-10-10' + INTERVAL 1 DAY);

How to compare a date when the date is stored as a varchar

The dates in my database are stored as varchars instead of date formats due to the way it was first built.
The dates look like this:
e.g. 1/3/2015 and
10/3/2015
I'm trying:
"SELECT COUNT(*) n FROM tracker WHERE TIMESTAMP(STR_TO_DATE(date, '%d/%m/%Y'))<=NOW()"
However, that's not working. It is returning the count of all records, regardless of the date.
How can I count only the records where the date is today or in the past?
You do not need TIMESTAMP():
SELECT COUNT(*) as n
FROM tracker
WHERE STR_TO_DATE(date, '%d/%m/%Y') <= NOW()
You should pay attention to the functions STR_TO_DATE and NOW(), the first return a date, the second is a timestamp.
When you convert STR_TO_DATE(date, '%d/%m/%Y') you will get a date with hours, minutes and seconds as 00:00:00
Using CURRENT_DATE perhaps will match more closely the original requirements
SELECT COUNT(*) as n
FROM tracker
WHERE STR_TO_DATE(date, '%d/%m/%Y') <= CURRENT_DATE
Also I suggest you to rename the column 'date'

Comparing date values of CURDATE() with a full timestamp field

I have a function that is placing timestamp values (YYYY-MM-DD HH:MM:SS) into META_VALUE column of table META.
What I want to do is to compare whether the date portion (YYYY-MM-DD) of the META_VALUE is equal to today (CURDATE()), disregarding the hour, minute and second (HH:MM:SS).
How can I accomplish this?
SELECT * FROM table WHERE <timestamp-field> BETWEEN 'YYYY-MM-DD 00:00:00' AND 'YYYY-MM-DD 23:59:59'
Allways avoid doing calculations on the field if possible: e.g.
SELECT * FROM table WHERE DATE(<timestamp-field>) = 'YYYY-MM-DD'
will calculate DATE() for ALL rows in that table, so you are really talking wasted cycles here
Simply use DATE:
SELECT * FROM table WHERE DATE(timestamp) = '2011-12-29'

Date SQL query doesn't work as expected

I have the following query:
SELECT * FROM incomings WHERE date >= '2011-04-01%' AND date <= '2011-04-29%'
And it shows results from 01-04 to 28-04. This may be a weird question but, it I think it should show results from 29-04 too, right?
What's wrong?
Your syntax is odd. That query would normally be written:
SELECT * FROM incomings WHERE date >= '2011-04-01' AND date <= '2011-04-29'
I think from the way that you're trying to query the data that your date column is actually a DATETIME or TIMESTAMP column. If that's the case then '2011-04-29%' will be being cast to '2011-04-29 00:00:00'
I would recommend you use this SQL instead:
SELECT * FROM incomings WHERE date >= '2011-04-01' AND date < '2011-04-30'
What is the purpose of the "%" here (besides making the date invalid) ?
If "date" is of type DATETIME, then :
'2011-04-29 00:00:00' is <= to '2011-04-29'
'2011-04-29 00:00:01' is not <= to '2011-04-29'
You don't need the leading %, the date without hours is interpreted as midnight (or the very start) of given date.