Arjun
Arjun

Reputation: 43

Date between query in mysql not generated correct output

I stored date field as Varchar. When I use this query :

SELECT date
FROM g_m_tit
WHERE date BETWEEN '01.10.2015' AND '31.10.2015';

it generates the wrong output, as shown below

enter image description here

Upvotes: 0

Views: 189

Answers (3)

Paul Maxwell
Paul Maxwell

Reputation: 35603

In your image note how the first 2 characters are between '01' and '31'. The between operator works on varchars using varchar "rules" e.g. '19' IS between '01' and '31' and that is why you are getting unwanted results. You are expecting date rules to be applied but your expectation isn't accurate.

Do not store dates as a string; but if you simply had to do it for some reason only a sequence such as YYYYMMDD allows you to reliably use between.

If you persist in storing the column as varchar with the pattern dd.mm.yyyy then try these:

SELECT
      `date`
FROM g_m_tit
WHERE str_to_date(`date`,'%d.%m.%Y') BETWEEN '2015-10-01' AND '2015-10-31';

SELECT
      `date`
FROM g_m_tit
WHERE str_to_date(`date`,'%d.%m.%Y') >= '2015-10-01') 
AND str_to_date(`date`,'%d.%m.%Y') < '2015-11-01';

both of these, as you can see, force you into changing the data, and you would need to do that every time you reference that "date" column - that is very inefficient.

Also, date is a reserved word, please avoid using such words as column names.

A final note: I prefer the second query above as I never use between for date ranges.

Upvotes: 1

spencer7593
spencer7593

Reputation: 108480

With VARCHAR column, comparing to strings, that will be a character by character comparison, from left to right.

If you want string comparisons to be used for "date" comparisons, the date values will need to be stored in a consistent and canonical format, with the year first, then the month, then the day. e.g. '2016.01.13'.

MySQL provides datatypes other than VARCHAR specifically for storing date and time values... DATE, DATETIME, TIMESTAMP.


Dealing with date values stored in VARCHAR columns, in the format you have, is going to be some messy SQL. And MySQL is going to have to scan all rows to evaluate the expression; it won't be able to use a range scan operation.

One way to do it is to convert the strings into DATE values, and compare the DATE values.

   WHERE STR_TO_DATE(`date`      ,'DD.MM.YYYY')
 BETWEEN STR_TO_DATE('01.10.2015','DD.MM.YYYY')
     AND STR_TO_DATE('31.10.2015','DD.MM.YYYY')

If there are any string values in date that can't be converted to a DATE, because the format doesn't match the specification, or an "invalid" date value, e.g. 32.13.2015, the STR_TO_DATE function will return a NULL or throw an error (depending the SQL_MODE setting).

Upvotes: 1

Vitaly
Vitaly

Reputation: 31

create new column with "date" or "bigint" type

Update all rows inserting value from old column to new (based on new column type)

Delete old column

Rename new one to "g_m_tit"

do not use varchar for dates! It causing probelms as u can see and its slower than date/bigint

To store date in:

"varchar(10)" u need 11 bytes + charset collate every query

"bigint" u need 8 bytes (available range condition)

"date" u need 3 bytes (available range, by part of date conditions and much more )

Upvotes: 0

Related Questions