यह पदानुक्रमित डेटा के लिए एक सभ्य डिज़ाइन की तरह नहीं दिखता है। आसन्नता सूची . जैसे अन्य दृष्टिकोण पर विचार करें ।
समाधान #1 - MySQL 8 JSON समर्थन:
MySQL 8 के साथ आप <का उपयोग कर सकते हैं कोड>JSON_ARRAYAGG()
और JSON_OBJECT()
केवल SQL के साथ JSON परिणाम प्राप्त करने के लिए:
select json_object(
'name', l1.level_1_name,
'children', json_arrayagg(json_object('name', l2.level_2_name, 'children', l2.children))
) as json
from level_1 l1
left join (
select l2.level_2_name
, l2.level_1_fk
, json_arrayagg(json_object('name', l3.level_3_name)) as children
from level_2 l2
left join level_3 l3 on l3.level_2_fk = l2.level_2_pk
group by l2.level_2_pk
) l2 on l2.level_1_fk = l1.level_1_pk
group by level_1_pk
नतीजा यह है:
{"name": "Bob", "children": [{"name": "Ted", "children": [{"name": "Fred"}]}, {"name": "Carol", "children": [{"name": "Harry"}]}, {"name": "Alice", "children": [{"name": "Mary"}]}]}
स्वरूपित:
{
"name": "Bob",
"children": [
{
"name": "Ted",
"children": [
{
"name": "Fred"
}
]
},
{
"name": "Carol",
"children": [
{
"name": "Harry"
}
]
},
{
"name": "Alice",
"children": [
{
"name": "Mary"
}
]
}
]
}
समाधान #2 - GROUP_CONCAT() के साथ JSON का निर्माण:
यदि नामों में कोई उद्धरण कैरेक्टर नहीं है, तो आप GROUP_CONCAT()
का उपयोग करके पुराने संस्करणों में मैन्युअल रूप से JSON स्ट्रिंग बना सकते हैं। :
$query = <<<MySQL
select concat('{',
'"name": ', '"', l1.level_1_name, '", ',
'"children": ', '[', group_concat(
'{',
'"name": ', '"', l2.level_2_name, '", ',
'"children": ', '[', l2.children, ']',
'}'
separator ', '), ']'
'}') as json
from level_1 l1
left join (
select l2.level_2_name
, l2.level_1_fk
, group_concat('{', '"name": ', '"', l3.level_3_name, '"', '}') as children
from level_2 l2
left join level_3 l3 on l3.level_2_fk = l2.level_2_pk
group by l2.level_2_pk
) l2 on l2.level_1_fk = l1.level_1_pk
group by level_1_pk
MySQL;
परिणाम वही होगा (देखें डेमो )
समाधान #3 - PHP ऑब्जेक्ट्स के साथ नेसेट संरचना का निर्माण:
आप एक सरल SQL क्वेरी भी लिख सकते हैं और PHP में नेस्टेड संरचना का निर्माण कर सकते हैं:
$result = $connection->query("
select level_1_name as name, null as parent
from level_1
union all
select l2.level_2_name as name, l1.level_1_name as parent
from level_2 l2
join level_1 l1 on l1.level_1_pk = l2.level_1_fk
union all
select l3.level_3_name as name, l2.level_2_name as parent
from level_3 l3
join level_2 l2 on l2.level_2_pk = l3.level_2_fk
");
परिणाम है
name | parent
----------------
Bob | null
Ted | Bob
Carol | Bob
Alice | Bob
Fred | Ted
Harry | Carol
Mary | Alice
नोट:नाम सभी तालिकाओं के साथ अद्वितीय होना चाहिए। लेकिन मैं नहीं जानता कि यदि डुप्लीकेट संभव होते तो आप किस परिणाम की अपेक्षा करते।
अब पंक्तियों को नाम से अनुक्रमित सरणी में ऑब्जेक्ट के रूप में सहेजें:
$data = []
while ($row = $result->fetch_object()) {
$data[$row->name] = $row;
}
$डेटा
अब इसमें शामिल होगा
[
'Bob' => (object)['name' => 'Bob', 'parent' => NULL],
'Ted' => (object)['name' => 'Ted', 'parent' => 'Bob'],
'Carol' => (object)['name' => 'Carol', 'parent' => 'Bob'],
'Alice' => (object)['name' => 'Alice', 'parent' => 'Bob'],
'Fred' => (object)['name' => 'Fred', 'parent' => 'Ted'],
'Harry' => (object)['name' => 'Harry', 'parent' => 'Carol'],
'Mary' => (object)['name' => 'Mary', 'parent' => 'Alice'],
]
अब हम नोड्स को एक लूप में लिंक कर सकते हैं:
$roots = [];
foreach ($data as $row) {
if ($row->parent === null) {
$roots[] = $row;
} else {
$data[$row->parent]->children[] = $row;
}
unset($row->parent);
}
echo json_encode($roots[0], JSON_PRETTY_PRINT);
परिणाम:
{
"name": "Bob",
"children": [
{
"name": "Ted",
"children": [
{
"name": "Fred"
}
]
},
{
"name": "Carol",
"children": [
{
"name": "Harry"
}
]
},
{
"name": "Alice",
"children": [
{
"name": "Mary"
}
]
}
]
}
यदि एकाधिक रूट नोड संभव हैं (level_1_name
. में एकाधिक पंक्तियां ), फिर उपयोग करें
json_encode($roots);