Преобразование строки совпадения группы MySQL в структуру объекта json через PHP - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть 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, агрегация запросов кажется корректной, поскольку я все еще далек от ожидаемого результата:

enter image description here

Используя PDO::FETCH_ASSOC выборку запроса вPHP я получаю на самом деле похожий ожидаемый результат массива.

Но главная проблема заключается в том, что агрегирование линеаданных просто в формате одной строки сгруппировано и объединено все вместе, а не в форме структуры объекта.(экран ниже)

enter image description here

Я прилагаю приведенные ниже примеры из запроса:

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 не очень хорошо оптимизированы, но они меня устраивают.Если у кого-то из нас есть более оптимизированное решение, пожалуйста, поделитесь им.Спасибо.

...