sql >> Database teknologi >  >> RDS >> Mysql

Opretter hierarkisk JSON fra MySQL-resultater og PHP til D3.js-træet?

Dette ligner ikke et anstændigt design for hierarkiske data. Overvej en anden tilgang, såsom adjacency list .

Løsning #1 - MySQL 8 JSON-understøttelse:

Med MySQL 8 kan du bruge JSON_ARRAYAGG() og JSON_OBJECT() for at få JSON-resultatet kun med SQL:

vælg json_object( 'name', l1.level_1_name, 'children', json_arrayagg(json_object('name', l2.level_2_name, 'children', l2.children))) som jsonfrom level_1 l1left join ( vælg l2.level_2_name , l2.level_1_fk , json_arrayagg(json_object('name', l3.level_3_name)) som børn fra level_2 l2 venstre slutter sig til level_3 l3 på l3.level_2_fk =l2.level_2_pk-gruppe på l2.level_level_k_1 på l2.level.k_1 l1.level_1_pkgroup efter level_1_pk 

Resultatet er:

{"name":"Bob", "children":[{"name":"Ted", "children":[{"name":"Fred"}]}, {"name" :"Carol", "children":[{"name":"Harry"}]}, {"name":"Alice", "children":[{"name":"Mary"}]}]} 

db-fiddle-demo

Formateret:

{ "name":"Bob", "children":[ { "name":"Ted", "children":[ { "name":"Fred" } ] }, { "name" :"Carol", "children":[ { "name":"Harry" } ] }, { "name":"Alice", "children":[ { "name":"Mary" } ] } ]} 

Løsning #2 - Konstruktion af JSON med GROUP_CONCAT():

Hvis navnene ikke indeholder nogen citattegn, kan du manuelt konstruere JSON-strengen i ældre versioner ved hjælp af GROUP_CONCAT() :

$query =<< 

Resultatet ville være det samme (se demo )

Løsning #3 - Konstruktion af nestet-struktur med PHP-objekter:

Du kan også skrive en enklere SQL-forespørgsel og konstruere den indlejrede struktur i PHP:

$result =$connection->query(" vælg level_1_name som navn, null som overordnet fra level_1 union alle vælg l2.level_2_name som navn, l1.level_1_name som forælder fra level_2 l2 join level_1 l1 på l1.level_1_pk =l2.level_1_fk union alle vælg l3.level_3_name som navn, l2.level_2_name som forælder fra level_3 l3 join level_2 l2 på l2.level_2_pk =l3.level_2_fk"); 

Resultatet er

navn | forælder----------------Bob | nullTed | BobCarol | BobAlice | BobFred | TedHarry | CarolMary | Alice

demo

Bemærk:Navnet skal være unikt langs alle tabeller. Men jeg ved ikke, hvilket resultat du ville forvente, hvis dubletter var mulige.

Gem nu rækkerne som objekter i en matrix indekseret med navnet:

$data =[]while ($row =$result->fetch_object()) { $data[$row->name] =$row;} 

$data vil nu indeholde

[ 'Bob' => (objekt)['name' => 'Bob', 'forælder' => NULL], 'Ted' => (objekt)['name' => 'Ted' , 'forælder' => 'Bob'], 'Carol' => (objekt)['name' => 'Carol', 'forælder' => 'Bob'], 'Alice' => (objekt)['navn ' => 'Alice', 'forælder' => 'Bob'], 'Fred' => (objekt)['name' => 'Fred', 'forælder' => 'Ted'], 'Harry' => (objekt)['name' => 'Harry', 'forælder' => 'Carol'], 'Mary' => (objekt)['name' => 'Mary', 'forælder' => 'Alice'] ,] 

Vi kan nu forbinde noderne i en enkelt sløjfe:

$roots =[];foreach ($data som $row) { if ($row->parent ===null) { $roots[] =$row; } else { $data[$row->parent]->children[] =$row; } unset($row->forælder);}echo json_encode($roots[0], JSON_PRETTY_PRINT); 

Resultatet:

{ "name":"Bob", "children":[ { "name":"Ted", "children":[ { "name":"Fred" } ] }, { "name" :"Carol", "children":[ { "name":"Harry" } ] }, { "name":"Alice", "children":[ { "name":"Mary" } ] } ]} 

demo

Hvis flere rodnoder er mulige (flere rækker i niveau_1_navn ), og brug derefter

json_encode($roots); 


  1. Fejl ved installation af MySQL-python med pip-installation i OSX, virtualenv

  2. Spatial Point-funktioner ved hjælp af Laravel Eloquent ORM

  3. Brug af PHP og MySQL til at udfylde dropdown

  4. C# svarende til SQL Server DataTypes