У меня есть 2 таблицы MySQL, первая из которых является родительской, а вторая - дочерней.Эти две таблицы имеют отношение 1: M .T_1
содержит список уникальных пользователей с некоторыми сведениями.И T_2
содержит весь список данных линии с координатами в определенной временной отметке для каждого пользователя.Дочерняя таблица T_2
имеет FK , который ссылается на PK в родительской таблице T_1
.Я поделился ниже CREATE STATEMENT:
CREATE TABLE `T_1` (
`id` varchar(45) DEFAULT NULL,
`value_1` tinyint(4) NOT NULL,
`personId` varchar(45) NOT NULL,
`value_2` varchar(45) NOT NULL,
`value_3` varchar(45) NOT NULL,
`Value_4` int(11) NOT NULL,
PRIMARY KEY (`personId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `T_2` (
`personId` varchar(45) NOT NULL,
`timestamp` varchar(45) NOT NULL,
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
KEY `user_fk_idx` (`personId`),
CONSTRAINT `user_fk` FOREIGN KEY (`personId`) REFERENCES `T_1` (`personId`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Я хотел бы получить в качестве окончательного результата JSON что-то вроде этого:
[
{
"id": "",
"value_1": true,
"personId": "1",
"value_2": "test",
"value_3": "test",
"value_4": 10,
"lineData": [
{
"timestamp": "some_date",
"x": 100,
"y": 250
},
{
"timestamp": "some_date",
"x": 100,
"y": 350
}
]
},
{
"id": "",
"value_1": true,
"personId": "2",
"value_2": "test",
"value_3": "test",
"value_4": 10,
"lineData": [
{
"timestamp": "some_date",
"x": 50,
"y": 450
},
{
"timestamp": "some_date",
"x": 80,
"y": 550
}
]
}
]
Это первый выбор запроса, который я сделал в порядкечтобы получить агрегацию всех T_2
записей для каждого T_1.personId
:
SELECT T_1.personId,GROUP_CONCAT(CONCAT(T_2.timestamp, T_2.x, T_2.y) SEPARATOR ' ')
FROM T_1
JOIN T_2
ON T_1.personId=T_2.personId
GROUP BY personId;
За исключением того, что мне нужно добавить также id
, value_1
, value_2
, value_3
, value_4
, агрегация запросов кажется корректной, поскольку я все еще далек от ожидаемого результата:
Используя PDO::FETCH_ASSOC
выборку запроса вPHP я получаю на самом деле похожий ожидаемый результат массива.
Но главная проблема заключается в том, что агрегирование линеаданных просто в формате одной строки сгруппировано и объединено все вместе, а не в форме структуры объекта.(экран ниже)
Я прилагаю приведенные ниже примеры из запроса:
array(7) {
["id"]=>
NULL
["value_1"]=>
string(1) "0"
["personId"]=>
string(2) "1"
["value_2"]=>
string(9) "test"
["value_3"]=>
string(4) "test"
["value_4"]=>
string(2) "10"
["linedata"]=>
string(359) "2018/09/15 10:00:05 AM1100950 2018/09/15 10:00:07 AM1100850 2018/09/15 10:00:09 AM1180800 2018/09/15 10:00:10 AM1280800 2018/09/15 10:00:15 AM1380800 2018/09/15 10:00:17 AM1480800 2018/09/15 10:00:20 AM1900800 2018/09/15 10:00:25 AM1930750 2018/09/15 10:00:40 AM1910440 2018/09/15 10:00:45 AM1250460 2018/09/15 10:01:25 AM1100455 2018/09/15 10:01:29 AM1100655"
}
}
Может бытьнужно было соединить квадратные и фигурные скобки в запросе выбора?
Может кто-нибудь подсказать, как получить правильную разделенную структуру для данных linea?Я предположил, что нам нужно использовать также некоторые постпроцессные вещи PHP, чтобы получить точную желаемую структуру вывода.
Обновление
Следуя предложению @Salman A, я настроил запрос, как показано ниже:
GROUP_CONCAT(CONCAT_WS(', ',timestamp,x, y) SEPARATOR '; ') as linedata_0
И я сохранил результат запроса в $query_result
,Затем я создал вложенный foreach, чтобы взорвать каждую строку с ;
и каждое значение каждой строки с ,
в $query_result['linedata_0']
.И я поместил взорванный результат в новый ключ под названием linedata_1
.Как показано ниже:
foreach ($query_result as $q_r){
$first_split = explode(";", $q_r["linedata_0"]);
foreach ($first_split as $f_s){
$second_split = explode(",", $f_s);
$query_result["linedata_1"][]= $second_split;
}
}
Я удалил элемент $query_result[0]["linedata_0"]
.И после этого я назначил значения ключа для каждого $query_result['linedata_1']
под-массива и сохранил в новом элементе с именем $query_result['linedata']
.После этого я удалил старый элемент $query_result['linedata_1']
с помощью команды unset
и в последнем foreach я преобразовал значения x
и y
из строки в целое число:
unset($query_result[0]["linedata_0"]);
foreach(($query_result["linedata_1"]) as $q_r) {
$keys = array('timestamp', 'x', 'y');
$query_result["linedata"][] = array_combine($keys, $q_r);
}
unset($query_result["linedata_1"]);
$index = 0;
foreach($query_result["linedata"] as $index=>$val) {
$query_result["linedata"][$index]["x"] = (int) $val["x"];
$query_result["linedata"][$index]["y"] = (int) $val["y"];
$index++;
}
С помощью этих PHPпостпроцессные операции Я получил именно ожидаемый результат . Вероятно, эти постпроцессные шаги в php не очень хорошо оптимизированы, но они меня устраивают.Если у кого-то из нас есть более оптимизированное решение, пожалуйста, поделитесь им.Спасибо.