I am currently developing an application that displays documents and allows the members to search for these documents by a number of different parameters, one of them being
Try to use CONCAT() and make it one field and compare .
Am not sure you can compare it as date after concatenation.
You can compare as integer.
concatinate year month day and make an integer like this 20101017 and compare.
Hopefully :)
To build a sortable date string from that, you'll need CONCAT
to join the bits together and LPAD
to make sure the month and day fields are two digits long. Something like this:
CONCAT(`year`,'-',LPAD(`month`,2,'00'),'-',LPAD(`day`,2,'00'))
Once you have that, you should be able to use BETWEEN
, as they'll be in a sortable format. However if you still need to convert them to actual datetime fields, you can wrap the whole thing in UNIX_TIMESTAMP()
to get a timestamp value.
So you'd end up with something like this:
SELECT UNIX_TIMESTAMP(CONCAT(`year`,'-',LPAD(`month`,2,'00'),'-',LPAD(`day`,2,'00'))) as u_date
WHERE u_date BETWEEN timestamp_1 and timestamp_2
However, be aware that this will be massively slower than if the field was just a simple timestamp in the first place. And you should definitely make sure you have an index on the year, month and day fields.
The simplest way to do this is:
DATE(CONCAT_WS('-', year, month, day))
LPAD is not necessary as @pbarney pointed out earlier. If you are comparing with another date object, it's not strictly necessary to wrap it with DATE as MySQL will cast it automatically:
some_date_field > CONCAT_WS('-', year, month, day)
You can use STR_TO_DATE() function.
When you have integer values for year, month and day you can make a DATETIME by combining MAKEDATE() and DATE_ADD(). MAKEDATE() with a constant day of 1 will give you a DATETIME for the first day of the given year, and then you can add to it the month and day with DATE_ADD():
mysql> SELECT MAKEDATE(2013, 1);
+-------------------+
| MAKEDATE(2013, 1) |
+-------------------+
| 2013-01-01 |
+-------------------+
mysql> SELECT DATE_ADD(MAKEDATE(2013, 1), INTERVAL (3)-1 MONTH);
+---------------------------------------------------+
| DATE_ADD(MAKEDATE(2013, 1), INTERVAL (3)-1 MONTH) |
+---------------------------------------------------+
| 2013-03-01 |
+---------------------------------------------------+
mysql> SELECT DATE_ADD(DATE_ADD(MAKEDATE(2013, 1), INTERVAL (3)-1 MONTH), INTERVAL (11)-1 DAY);
| DATE_ADD(DATE_ADD(MAKEDATE(2013, 1), INTERVAL (3)-1 MONTH), INTERVAL (11)-1 DAY) |
+----------------------------------------------------------------------------------+
| 2013-03-11 |
+----------------------------------------------------------------------------------+
So to answer the OP's question:
SELECT * FROM `date`
WHERE DATE_ADD(DATE_ADD(MAKEDATE(year, 1), INTERVAL (month)-1 MONTH), INTERVAL (day)-1 DAY)
BETWEEN '2013-01-01' AND '2014-01-01';
Expanding this answer, here's my take on it:
DELIMITER $$
CREATE FUNCTION fn_year_month_to_date(var_year INTEGER,
var_month enum('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12')
)
RETURNS DATE
BEGIN
RETURN (MAKEDATE(var_year, 1) + INTERVAL (var_month - 1) MONTH);
END $$
DELIMITER ;
SELECT fn_year_month_to_date(2020, 12)
;