Предположим, у нас есть таблица person
и таблицу phone
и связь между ними один ко многим.
Мне нужно получить такой результат с помощью одного запроса.
[
{
name:"abc",
lname:"def",
phones:[
{
dial_code="+1",
number:"12345667"
},
{
dial_code="+1",
number:"12345667"
}
]
},
{
name:"xyz",
lname:"lmn",
phones[
{
dial_code="+2",
number:"2643525"
}
]
},
{...}
]
Я могу сделать это по нескольким запросам, например, сначала получить всех persons
а затем получить их phones
один за другим, но я думаю, что это так странно и нужно много времени и снизить производительность. и если я получу все данные, присоединив таблицу, это не будет похоже на этот формат JSON
.
Любая идея будет оценена по достоинству.
Извините за мой плохой английский.
Во-первых, вы не можете получить желаемый результат с несколькими phone
внутри каждого person
с одним запросом.
Теперь, выполнив запрос внутри person
цикла будет очень влиять на производительность скрипта, если есть много данных. Таким образом, во-первых, вам нужно выполнить запрос для извлечения всех лиц (например, n
человек). Затем вам нужно снова зациклить все n
люди, чтобы забрать их соответствующие телефоны. Поэтому вам нужно запустить что-то вроде следующего внутри $persons
loop n
раз:
SELECT * FROM phone WHERE person_id = [$person_id]
Поэтому таким образом вам нужно выполнить n+1
запросов.
Чтобы преодолеть эту проблему с запросом n+1
мы можем применить методологию, которая называется eager loading
. Здесь также необходимо выполнить первый запрос для извлечения всех лиц, а затем написать запрос для извлечения всех телефонов, принадлежащих тем, которые были получены:
SELECT * FROM person
Результат ($ человек):
id name
5 John
10 Bob
20 Jenna
SELECT * FROM phone WHERE person_id IN (5,10,20)
Результат ($ телефонов):
id person_id dial_code number
1 5 +2 12345
2 10 +1 12312
3 20 +1 98765
Теперь мы объединим эти два результата в PHP-скриптах для создания желаемого массива. Таким образом, мы пишем только два запроса вместо n+1
запросов.
Вы можете написать PHP-скрипт следующим образом, чтобы объединить два набора результатов:
// Create an array of phones with person_id as key
$phones_with_person_id_as_key = [];
foreach($phones as $key => $phone) {
$phones_with_person_id_as_key[$phone->person_id][$key] = $phone;
}
// Loop $persons array and add phones to person object
foreach($persons as $key => $person) {
// create phones key and add data
if (!empty($phones_with_person_id_as_key[$person->id])) {
$person->phones = $phones_with_person_id_as_key[$person->id];
}
else {
$person->phones = [];
}
}
Теперь $persons
содержит отформатированный желаемый результат.