Импорт нулевых и неправильно отформатированных значений даты и времени в столбец даты и времени MySQL

Я использую базу данных MySQL с интерфейсом Sequel Pro и новичок в SQL. Я пытаюсь импортировать данные из CSV-файла, и один из столбцов, в которые я импортирую, имеет тип datetime. Однако формат, в котором я получаю данные, — мм/дд/гг чч:мм AM/PM или null. Первоначально я изменил тип столбца на varchar, чтобы избежать проблемы, но теперь мне нужно выполнить некоторые функции даты для данных, которые не могут быть выполнены, если столбец не имеет тип и формат даты и времени, поэтому мне нужен способ преобразовать входящие данные в правильный формат даты и времени.

Кроме того, оператор импорта будет выполняться людьми, не знакомыми с SQL или базами данных, поэтому было бы предпочтительнее, чтобы они просто щелкнули файл -- импорт и не вводили ничего сложного в командную строку mysql. Кроме того, после выполнения запроса мне нужно экспортировать данные в том же формате, в котором они были получены (мм/дд/гг чч:мм AM/PM или ноль).

Вот несколько примеров значений из столбца:

Completion Time
null
6/16/14 10:33 AM
null
null
6/16/14 13:03 PM
6/17/14 13:53 PM
6/18/14 14:38 PM
6/18/14 14:52 PM
6/19/14 13:13 PM
6/18/14 18:56 PM
6/18/14 19:02 PM
null

Возможно, простое решение, которое я нашел, может быть не такой уж хорошей идеей после пары часов поиска в Google, было бы сохранить тип столбца как varchar, а затем каким-то образом извлечь только часть входящих данных mm/dd/yy, преобразовать это для правильного формата даты MySQL, а затем выполнять мои функции даты.

В любом случае любая помощь будет принята с благодарностью.


person djar    schedule 23.07.2014    source источник
comment
Вам придется преобразовать входящую дату, так как это не корректный формат для MySQL. Он не может достоверно сказать, какая часть мм, а какая дд. Вывод позже может быть повторно преобразован с использованием этого dev.mysql.com/doc/refman/5.5/ru/   -  person ToBe    schedule 23.07.2014
comment
Есть ли способ настроить хранимую процедуру или триггер для преобразования входящей даты?   -  person djar    schedule 23.07.2014


Ответы (2)


Это не очень сложно с функциями даты и времени MySQL. STR_TO_DATE делает то, что вам нужно для импорта:

формат, в котором я получаю данные, — мм/дд/гг чч:мм AM/PM или null.

Вы получаете значение DATETIME с помощью

STR_TO_DATE(yourValue, '%m/%d/%y %h:%i %p')

Вы найдете спецификаторы для STR_TO_DATE в описании функции DATE_FORMAT

Для экспорта вы делаете обратное с уже упомянутой функцией DATE_FORMAT с точно такой же строкой формата:

SELECT DATE_FORMAT(your_datetime_col, '%m/%d/%y %h:%i %p')

Взгляните на эту демонстрацию

Вы можете выполнить преобразование в операторе INSERT следующим образом:

INSERT INTO example (date_time) VALUES 
(STR_TO_DATE('09/26/14 07:30 AM', '%m/%d/%y %h:%i %p'));

Посмотрите, как это работает в обновленной демонстрации.

Настройка импорта с помощью LOAD DATA INFILE

Пусть у нас есть таблица example с двумя столбцами id и date_time как

CREATE TABLE example (
    id INT NOT NULL PRIMARY KEY,
    date_time DATETIME
);

У нас есть еще файл CSV example.csv с такими данными:

id,date
1,09/26/14 07:30 AM
2,07/23/14 07:30 PM

Чтобы импортировать этот файл с помощью LOAD DATA INFILE, вы будете использовать этот оператор:

LOAD DATA INFILE 'path/on/server/to/example.csv'
INTO TABLE example
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 LINES             -- because of the column headers in the first line
(id, @var1)                -- You've got to map every field of your csv file to a column
                           -- of your table.
                           -- You've got to list the names of the columns of your table,
                           -- not the headers in the csv file.
                           -- if one field should be ignored, use another variable for this
                           -- field.
SET date_time = STR_TO_DATE(@var1, '%m/%d/%y %h:%i %p');

Если ваши даты в файлах csv содержат литеральную строку «null», которая указывает значение NULL, используйте оператор CASE:

date
09/26/14 07:30 AM
null
07/23/14 07:30 PM

тогда мы должны использовать

LOAD DATA INFILE 'path/on/server/to/example.csv'
INTO TABLE example
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n' -- your line endings
IGNORE 1 LINES             -- because of the column headers in the first line
(@var1)                     -- read all parts of the date in variables
SET completionTime = CASE 
                     WHEN @var1 = 'null' THEN NULL 
                     ELSE STR_TO_DATE(@var1, '%m/%d/%y %h:%i %p')
                     END;

Проблема с полями, содержащими разделитель, в данном случае запятую, вы уже решили, заключив эти поля (или просто все) в закрывающий символ.

Но мы действительно должны взглянуть на ваш реальный формат.

person VMai    schedule 23.07.2014
comment
Мои поля не заключены в кавычки, и я изменил имена полей в своем комментарии для анонимности, как вы сказали. Проблема в том, что столбец datetime полностью равен нулю, а в других столбцах все данные перепутаны, где некоторые символы из столбца datetime появляются в других столбцах, заменяя фактические данные, которые кричат ​​там, а затем их данные перемещаются по одному столбцу - person djar; 24.07.2014
comment
@djar Поскольку ваш столбец «Дата» является первым, не могли бы вы дать мне одну или две строки с датой (это не должно быть проблемой) и анонимными данными из второго поля. Очевидно, что это испорчено только тогда. Если это работает для столбца даты и первого поля, то остальное не должно быть большой проблемой. - person VMai; 24.07.2014
comment
@djar звучит так, как будто у вас есть запятые внутри ваших данных, которые портят отображение - person Michael McGriff; 24.07.2014
comment
@MichaelMcGriff Я тоже это подозреваю. В строках 10\20\14, 08:12 AM или что-то в этом роде. - person VMai; 24.07.2014
comment
@MichaelMcGriff Спасибо, я этого не заметил, вы правы. Но теперь, почему мой столбец даты и времени по-прежнему содержит только нулевые значения? - person djar; 24.07.2014
comment
@djar: Кажется, это несложно: скопируйте дату в свой вопрос, чтобы мы могли увидеть формат. - person VMai; 24.07.2014
comment
@djar я предполагаю, что STR_TO_DATE по какой-то причине не работает. Разместите некоторые фактические значения в этом столбце, чтобы мы могли видеть, что именно он пытается преобразовать. - person Michael McGriff; 24.07.2014
comment
Отредактировано под вопросом - person djar; 24.07.2014
comment
@djar Но запятой нет. И действительно ли ваш CSV-файл содержит строку «null»? Если да, то мы должны учитывать это при импорте. - person VMai; 24.07.2014
comment
Он содержит фактическую строку null. И то, что я разместил, было только одним столбцом, моя проблема возникла из-за того, что другие столбцы содержали запятые. - person djar; 24.07.2014
comment
@VMai проще, чем объединение полей, при работе с CSV-файлом, содержащим запятые, используется предложение, заключенное в (например, заключенное в ''). Хотя у меня все еще есть проблема со всеми моими значениями даты и времени, записанными как нулевые - person djar; 24.07.2014
comment
@djar, в этом случае вы можете использовать регистр, см. Последнее редактирование. - person VMai; 24.07.2014
comment
Пробовал. Все еще получаю только нулевые значения в столбце даты и времени. Вот код: load data local infile '/Users/me/Downloads/file.csv'into table tableName fields terminated by ',' enclosed by ‘“' lines terminated by '\r\n' (@var1, a, b, c, d, ...) SET completionTime = Case when @var1 = 'null' then NULL else STR_TO_DATE(@var1, '%m/%d/%y %h:%i %p') end; - person djar; 24.07.2014

Настоящий ответ на ваш вопрос:

Если у вас есть неспециалисты, выполняющие импорт Sequel Pro и нуждающиеся в обработке данных, вам необходимо написать и импортировать/экспортировать скрипт, из которого пользователи смогут загружать и скачивать таблицу Excel.

Однако...

У меня была аналогичная проблема с импортом дат в Sequel Pro. Итак, вот «половинчатое» решение. Бери из него что хочешь.

(Примечание: этот вопрос был задан 5 лет назад, поэтому он предназначен для всех, кто сталкивался с этим вопросом и сталкивался с похожей проблемой Sequel Pro.)

Это половинчатое решение:

Сначала переформатируйте DateTime внутри Excel.

  1. выберите столбец
  2. Перейдите в Формат> Ячейки
  3. Выберите «Пользовательский»
  4. Для типа используйте "yyyy-mm-dd hh:mm:ss"
  5. Для «нулевых» значений введите явно неправильную дату, например «2099-01-01 00:00:00:00».

Импортировать в Sequel Pro.

  1. Открытое продолжение Pro
  2. Перейдите в «Вид»> «Показать консоль» (сделайте это, чтобы избежать сбоя импорта Sequel Pro CSV)
  3. Откройте подключение к базе данных и выберите таблицу.
  4. Импортируйте CSV-файл.
  5. Обратите внимание на любые возникающие ошибки

Очистите данные после импорта (я же говорил, что это половинчатое решение).

  1. В Sequel Pro запустите этот запрос: UPDATE your_table SET your_column = NULL WHERE your_column = '2099-01-01 00:00:00:00';
person Adam    schedule 08.01.2020