繁体   English   中英

从 MySQL 中的日、月、年字段创建日期

[英]Create date from day, month, year fields in MySQL

我目前正在开发一个显示文档的应用程序,并允许成员通过许多不同的参数搜索这些文档,其中一个参数是日期范围。

我遇到的问题是数据库模式不是由我自己开发的,并且数据库的创建者创建了一个包含“日”、“月”、“年”字段的“日期”表。

我想知道如何从表中选择特定的日、月、年并在 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;

当您有年、月和日的整数值时,您可以通过组合 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';

您可以使用STR_TO_DATE()函数。

要从中构建可排序的日期字符串,您需要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

但是,要知道,这将是大量比如果该字段只是摆在首位简单的时间戳慢。 而且你绝对应该确保你有一个关于年、月和日字段的索引。

最简单的方法是:

DATE(CONCAT_WS('-', year, month, day))

正如@pbarney 之前指出的那样,LPAD 不是必需的。 如果您正在与另一个日期对象进行比较,则没有必要用 DATE 包装它,因为 MySQL 会自动转换它:

some_date_field > CONCAT_WS('-', year, month, day)

尝试使用 CONCAT() 并将其设为一个字段并进行比较。

我不确定您是否可以将其作为连接后的日期进行比较。

您可以作为整数进行比较。

连接年月日并制作这样的整数 20101017 并进行比较。

希望 :)

扩展这个答案,这是我的看法:

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)
;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM