我目前正在开发一个显示文档的应用程序,并允许成员通过许多不同的参数搜索这些文档,其中一个参数是日期范围。
我遇到的问题是数据库模式不是由我自己开发的,数据库的创建者创建了一个'日期'表,其中包含'day','month','year'字段。
我想知道如何从表中选择特定的日,月,年并在SQL中创建日期对象,以便我可以使用BETWEEN比较用户输入的日期。
以下是日期表的结构:
CREATE TABLE IF NOT EXISTS `date` (
`deposition_id` varchar(11) NOT NULL default '',
`day` int(2) default NULL,
`month` int(2) default NULL,
`year` int(4) default NULL,
PRIMARY KEY (`deposition_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
答案 0 :(得分:44)
如果您有年,月和日的整数值,则可以通过组合MAKEDATE()和DATE_ADD()来创建DATETIME。 MAKEDATE()的常数为1天将为您提供给定年份第一天的DATETIME,然后您可以使用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 |
+----------------------------------------------------------------------------------+
所以回答OP的问题:
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';
答案 1 :(得分:33)
您可以使用STR_TO_DATE()功能。
答案 2 :(得分:17)
要从中构建可排序日期字符串,您需要CONCAT
将这些位加在一起LPAD
以确保月份和日期字段长度为两位数。像这样:
CONCAT(`year`,'-',LPAD(`month`,2,'00'),'-',LPAD(`day`,2,'00'))
完成后,您应该可以使用BETWEEN
,因为它们将采用可排序的格式。但是,如果您仍然需要将它们转换为实际的日期时间字段,则可以将整个内容包装在UNIX_TIMESTAMP()
中以获取时间戳值。
所以你最终得到这样的东西:
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
但是,请注意,这个字段大于比字段只是一个简单的时间戳。你一定要确保你有年,月,日字段的索引。
答案 3 :(得分:3)
最简单的方法是:
DATE(CONCAT_WS('-', year, month, day))
LPAD是没有必要的,正如@pbarney先前指出的那样。如果你要与另一个日期对象进行比较,那么用DATE包装它并不是绝对必要的,因为MySQL会自动将它包装起来:
some_date_field > CONCAT_WS('-', year, month, day)
答案 4 :(得分:1)
尝试使用CONCAT()并将其设为一个字段并进行比较。
我不确定您可以在连接后将其与日期进行比较。
您可以比较为整数。
汇总年月日并制作一个像20101017这样的整数并进行比较。
希望:)
答案 5 :(得分:0)
扩展this answer,这是我的看法:
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)
;