Создать дату из поля день, месяц, год в MySQL - PullRequest
37 голосов
/ 18 октября 2010

В настоящее время я разрабатываю приложение, которое отображает документы и позволяет членам выполнять поиск этих документов по ряду различных параметров, одним из которых является диапазон дат.

Проблема, с которой я столкнулся, заключается в том, что схема базы данных была разработана не мной, а создатель базы данных создал таблицу «date» с полями для «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;

Ответы [ 5 ]

44 голосов
/ 23 декабря 2013

Если у вас есть целочисленные значения для года, месяца и дня, вы можете создать DATETIME, комбинируя MAKEDATE () и DATE_ADD ().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                                                                       |
+----------------------------------------------------------------------------------+

ответить на вопрос ОП:

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';
34 голосов
/ 18 октября 2010

Вы можете использовать функцию STR_TO_DATE () .

17 голосов
/ 18 октября 2010

Чтобы построить сортируемую строку даты из этого, вам нужно CONCAT, чтобы объединить биты, и LPAD, чтобы убедиться, что поля месяца и дня состоят из двух цифр.Примерно так:

CONCAT(`year`,'-',LPAD(`month`,2,'00'),'-',LPAD(`day`,2,'00'))

Как только вы это сделаете, вы сможете использовать BETWEEN, так как они будут в сортируемом формате.Однако, если вам все еще нужно преобразовать их в фактические поля даты и времени, вы можете обернуть все это в UNIX_TIMESTAMP(), чтобы получить значение метки времени.

Таким образом, вы получите нечто вроде этого:1011 *

Однако имейте в виду, что это будет на значительно * на 1014 * медленнее, чем если бы поле было просто простой отметкой времени.И вам обязательно нужно убедиться, что у вас есть индекс для полей года, месяца и дня.

3 голосов
/ 19 апреля 2018

Самый простой способ сделать это:

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

LPAD не требуется, как @pbarney указывал ранее.Если вы сравниваете с другим объектом даты, нет необходимости заключать его в DATE, так как MySQL автоматически его приведёт:

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

1 голос
/ 18 октября 2010

Попробуйте использовать CONCAT (), сделайте одно поле и сравните.

Не уверен, что вы можете сравнить его как дату после объединения.

Вы можете сравнить как целое число.

конкатенируйте число год-месяц и сделайте целое число, подобное этому 20101017, и сравните.

Надеюсь:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...