2017-02-17 11 views
2

Я использую тип данных MySQL json для хранения строки JSON. В строке JSON находятся два поля: entry_time и entry_date. Значения этих полей сохраняются в формате ISO 8609 следующим образом:Извлечение дат ISO из JSON Тип данных

entry_date:2017-02-15T00:00:00.00Z 
entry_time:0000-00-00T04:35:51.29Z 

Я пытаюсь создать виртуальный столбец из этих двух атрибутов. Поскольку MySQL 5.7 имеет набор NO_ZERO_DATE, я не вижу способа извлечь эти значения в качестве столбцов даты и времени. Вот что я пробовал:

alter table odh 
add entry_time time GENERATED ALWAYS AS (REPLACE,(json_extract(jdoc,'$.entry_time')),'0000-00-00T','') 

Но я не могу получить работу сота.

+0

Я рекомендую создать нормализованную структуру таблицы для хранения массива JSON, а затем PHP-скрипт, чтобы переместить все массивы в новую таблицу (ы) и никогда больше не хранить другой массив в базе данных. Конечно, это больше работает впереди, но жизнь будет легче после. – CptMisery

+0

Существует множество преимуществ для хранения данных в новом типе данных JSON MySQL. –

ответ

0

Там в другого проблемы мимо NO_ZERO_DATE проблемы: MySQL не использует ISO 8601 для даты, он использует ISO 9075 или даты SQL (на самом деле он использует все виды форматов, обработка даты MySQL довольно хаотичная). Есть некоторые тонкие отличия, самое большое существо, что 9075 не имеет T в середине. Большинство API-интерфейсов date справляются с этим, делая T необязательным, но не MySQL.

mysql> select time('1234-01-01T04:35:51.29Z'); 
+---------------------------------+ 
| time('1234-01-01T04:35:51.29Z') | 
+---------------------------------+ 
| 00:12:34      | 
+---------------------------------+ 
1 row in set, 1 warning (0.00 sec) 

Вместо того, чтобы давать ошибку или игнорировать T, MySQL дал отвратительно неправильный ответ.

mysql> select time('1234-01-01 04:35:51.29Z'); 
+---------------------------------+ 
| time('1234-01-01 04:35:51.29Z') | 
+---------------------------------+ 
| 04:35:51.29      | 
+---------------------------------+ 
1 row in set, 1 warning (0.00 sec) 

Теперь все в порядке.

Простейшей задачей является заменить Т пространством. Тогда будет работать TIME().

mysql> select time(replace('0000-00-00T04:35:51.29Z', 'T', ' ')); 
+------------------------------------------------+ 
| time(substring('0000-00-00T04:35:51.29Z', 12)) | 
+------------------------------------------------+ 
| 04:35:51.29         | 
+------------------------------------------------+ 
1 row in set, 1 warning (0.00 sec) 

дата часть будет обрабатываться DATE(), потому что MySQL будет просто игнорировать все остальное.

mysql> select date('2017-02-15T00:00:00.00Z'); 
+---------------------------------+ 
| date('2017-02-15T00:00:00.00Z') | 
+---------------------------------+ 
| 2017-02-15      | 
+---------------------------------+ 
1 row in set, 1 warning (0.01 sec) 

Вместо того, чтобы хранить отдельные даты и время столбцов, я настоятельно рекомендую вам объединить их в единую datetime колонну. Особенно, если они должны представлять одно событие (то есть, 4: 35: 51,29, 2017-20-15). Это значительно упростит сравнение, и вы всегда можете извлечь детали даты и времени с помощью DATE() и TIME().

-1

Не уверен, но вы можете найти некоторые из этих полезных. Предполагая, что вы начинаете с строкой JSON привезены из базы данных:

$jsonstring = '{ 
    "entries": [{ 
     "entry_date": "2017-02-15T00:00:00.00Z", 
     "entry_time": "0000-00-00T04:35:51.29Z" 
    }, { 
     "entry_date": "2017-02-16T00:00:00.00Z", 
     "entry_time": "0000-00-00T05:21:08.12Z" 
    }, { 
     "entry_date": "2017-02-17T00:00:00.00Z", 
     "entry_time": "0000-00-00T07:14:55.04Z" 
    }] 
}'; 

Следующий код будет преобразовать его в одно поле:

$json = json_decode($jsonstring, true); 

//display the json string before conversion 
echo "<pre>"; 
print_r($json['entries']); 
echo "</pre>"; 


$myArray = []; 
for($i = 0; $i < count($json['entries']); $i++) { 
    $myArray[] = substr($json['entries'][$i]['entry_date'], 0, 10). 
     substr($json['entries'][$i]['entry_time'], 10); 
} 
//display the json string after conversion 
echo "<pre>"; 
print_r($myArray); 
echo "</pre>"; 

Результат будет выглядеть следующим образом:

Array 
(
    [0] => 2017-02-15T04:35:51.29Z 
    [1] => 2017-02-16T05:21:08.12Z 
    [2] => 2017-02-17T07:14:55.04Z 
) 
+0

Этот код НЕ является SQL. Это похоже на PHP. OP ничего не сказал о PHP, так что нет, это не полезно. Вы, кажется, не понимаете концепцию виртуальных столбцов. – hackel