Как заменить текстовые символы только в столбце со значениями даты, но с типом данных VARCHAR в MySQL? - PullRequest
1 голос
/ 14 февраля 2020

У меня есть таблица со столбцом дат, в которой были различные значения, которые были очищены от дат Excel и c до mysql дат, и последний шаг, который я хочу выполнить, - это удалить все не датированные значения в столбце перед тем, как запустить команду alter, чтобы изменить тип данных на DATE, но, к сожалению, написанный мной запрос вызывает у меня несколько проблем. Ниже приведен пример моих дат:

CREATE TABLE `date_checks` 
        (  
        `Start_Date` varchar(255) DEFAULT NULL
        );

Мои вставки:

INSERT INTO `date_checks` (`Start_Date`) VALUES
('04/04/2018'),
('01/05/2018'),
('3 years'),
('28/05/2018');

Мой вывод

Start_Date
    04/04/2018
    01/05/2018
    3 years
    28/05/2018

Запущенный мной запрос следующее:

UPDATE 'date_checks' SET Start_Date = '' WHERE Start_Date NOT REGEXP '^[0-9]';

Теперь я предполагаю, потому что у меня есть значение 3 в начале моей 3-й строки, это не будет удалено, поэтому я просто хотел получить некоторую помощь, чтобы убедиться, что я делаю это правильный путь, как все, что я хотел бы в этом столбце, это значения даты. REGEXP, который я написал, ищет все, что не начинается с числа, но я предполагаю, что мне нужно расширить его, чтобы в столбце были даты, чтобы он был более точным c и точным.

Если приведенный выше код работает нормально, то я изменю тип данных следующим образом:

ALTER TABLE date_checks MODIFY Start_Date DATE;

Буду признателен, если кто-нибудь посоветует, что я поступаю правильно.

1 Ответ

2 голосов
/ 14 февраля 2020

MySQL не понимает даты в формате ДД / ММ / ГГГГ. Если вы сделаете показанный оператор ALTER TABLE, он не сможет преобразовать эти даты в значение типа DATE.

Вам необходимо преобразовать строки в формат YYYY-MM-DD.

I рекомендуем начать с нового столбца:

ALTER TABLE date_checks ADD COLUMN Start_Date2 DATE;

Затем скопируйте значения в новый столбец.

UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d/%m/%Y');

Если строка типа «3 года» не в формате которая соответствует строке формата в этой функции, затем STR_TO_DATE () возвращает NULL.

Так что после этого ОБНОВЛЕНИЯ вы скопируете большинство ваших дат в надлежащий формат, но те, которые не могут быть проанализированы, будут равны NULL. .

Затем вы можете проверить наличие странных случаев, которые не удалось проанализировать. Их может быть достаточно, чтобы вы могли обновить их в новом столбце вручную.

SELECT Start_Date FROM date_checks WHERE Start_Date2 IS NULL;

После того, как вы вручную присвоили все, что хотите сохранить, оставшиеся строки Start_Date хранить не стоит. Затем вы можете свободно удалить старый столбец и переименовать новый.

ALTER TABLE date_checks DROP COLUMN Start_Date, 
    CHANGE COLUMN Start_Date2 Start_Date DATE;

Повторный комментарий:

Как изменить код обновления на принять оба?

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

UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d/%m/%Y');
UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d-%m-%Y') WHERE Start_Date2 IS NULL;
UPDATE date_checks SET Start_Date2 = STR_TO_DATE(Start_Date, '%d.%m.%Y') WHERE Start_Date2 IS NULL;
...other formats...

Таким образом, после каждого прохода меньшее количество строк будет иметь значение NULL для Start_Date2. Вы продолжаете пробовать другие форматы по мере необходимости, пока либо не останется NULL, либо вы не захотите сдаться, потому что последние несколько отставших не разбираются.

Как и то, что вы делаете, если остался один, но строка в Start_Date гласит: «Старее моего языка и немного старше моих зубов»?

Если вы действительно если это нужно сделать за один проход, вы можете использовать COALESCE () с несколькими попытками:

UPDATE date_checks SET Start_Date2 = COALESCE(
  STR_TO_DATE(Start_Date, '%d/%m/%Y'),
  STR_TO_DATE(Start_Date, '%d-%m-%Y'),
  STR_TO_DATE(Start_Date, '%d.%m.%Y')
  ...other formats...
);

COALESCE () возвращает свой первый ненулевой аргумент. Поэтому он будет пробовать каждый из этих вызовов STR_TO_DATE () по порядку, слева направо, и результат будет первым, который завершится успешно. Или же NULL, если ни один из них не удался.

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