Упростите запрос, чтобы сделать столбец TIMESTAMP - PullRequest
0 голосов
/ 28 января 2019

У меня есть таблица со столбцами 'year', 'month', 'day', 'hour' и 'minute' отдельно.

Все столбцы INTEGER, кроме 'month' (VARCHAR), и я добавил новый столбецчтобы сложить все вместе, 'date_time' (TIMESTAMP).

+------+-------+------+------+--------+-----------+
| year | month |  day | hour | minute | date_time |
+------+-------+------+------+--------+-----------+
| 1987 | 12    |   15 |    9 |     25 |   <NULL>  |
| 1997 | 10    |   10 |   10 |     40 |   <NULL>  |
| 1994 | 08    |    9 |    6 |     30 |   <NULL>  |
+------+-------+------+------+--------+-----------+

Я сделал запрос, чтобы заполнить столбец 'date_time' следующим образом:

UPDATE dates
SET date_time =
    COALESCE(
        STR_TO_DATE(
            CASE WHEN
                CONCAT(
                    year,
                    '-',
                    CASE WHEN LPAD(month, 2, 0) BETWEEN 1 AND 12 THEN LPAD(month, 2, 0) ELSE NULL END,
                    '-',
                    CASE WHEN LPAD(day, 2, 0) BETWEEN 1 AND 31 THEN LPAD(day, 2, 0) ELSE NULL END,
                    ' ',
                    CASE WHEN LPAD(hour, 2, 0) BETWEEN 0 AND 23 THEN LPAD(hour, 2, 0) ELSE NULL END,
                    ':',
                    CASE WHEN LPAD(minute, 2, 0) BETWEEN 0 AND 59 THEN LPAD(minute, 2, 0) ELSE NULL END,
                    ':00'
                )
            LIKE '%NULL%' THEN NULL
            ELSE
                CONCAT(
                    year,
                    '-',
                    CASE WHEN LPAD(month, 2, 0) BETWEEN 1 AND 12 THEN LPAD(month, 2, 0) ELSE NULL END,
                    '-',
                    CASE WHEN LPAD(day, 2, 0) BETWEEN 1 AND 31 THEN LPAD(day, 2, 0) ELSE NULL END,
                    ' ',
                    CASE WHEN LPAD(hour, 2, 0) BETWEEN 0 AND 23 THEN LPAD(hour, 2, 0) ELSE NULL END,
                    ':',
                    CASE WHEN LPAD(minute, 2, 0) BETWEEN 0 AND 59 THEN LPAD(minute, 2, 0) ELSE NULL END,
                    ':00'
                )
            END,
            '%Y-%m-%d %H:%i:%s'
        ),
        '0000-00-00 00:00:00'
    );

Это сработало, но ... Мой вопросесли есть более простой способ написать запрос, чтобы сделать то же самое.

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Установка числа или строки в формате "ГГГГММДД" в функции DATE() приводит к ДАТЕ.

А функция MAKETIME() принимает часы, минуты и секунды для возврата ВРЕМЕНИ.

Затем, когда вы объединяете ДАТУ и ВРЕМЯ с пробелом между ними, полученную строку можно поместить в DATETIME или TIMESTAMP.

UPDATE dates
SET date_time = CONCAT(DATE(year*10000 + month*100 + day),' ',MAKETIME(hour,minute,0));

Проверка на db <> скрипка здесь

0 голосов
/ 28 января 2019

Вы можете использовать STR_TO_DATE для преобразования строки в datetime.Второй аргумент - это спецификатор формата, который вы можете использовать для описания формата ваших входных данных.Для некоторых вариантов использования доступны спецификаторы формата, например:

  • %c: Месяц в цифрах, например, 1, 2, 3… 12
  • %e:День месяца без начальных нулей, например, 1,2,… 31
  • %k: час в 24-часовом формате без начального нуля, например, 0,1,2… 23

Я не вижу спецификатора формата для «минут без начальных нулей» и «секунд без начальных нулей», но, похоже, не вызывает проблем их обработка в MySQL (я тестировал на MySQL 8.0).

Итак, я думаю, что вы могли бы сделать:

UPDATE dates 
SET datetime = STR_TO_DATE(
    CONCAT(year, '-', month, '-', day, ' ', hour, ':', minute, ':', second),
    '%Y-%c-%e %k:%i:%s'
)
...