PHP / mySQL - как извлечь вложенные строки в многомерный массив - PullRequest
4 голосов
/ 10 декабря 2008

Исходя из другого моего вопроса , где я научился никогда НИКОГДА не использовать db-запросы внутри циклов, следовательно, мне нужно научиться извлекать все данные удобным способом, прежде чем я буду проходить через него.

Допустим, у меня есть две таблицы «весы» и «предметы». Каждый элемент в элементах принадлежит одной шкале в масштабах и связан с внешним ключом (scaleID). Я хочу извлечь все эти данные в структуру массива в одном запросе, так что первое измерение - это все шкалы со всеми столбцами и вложенные во все элементы одной шкалы все столбцы.

Результат будет примерно таким:

scale 1, scaleParam1, scaleParam2, ...
....item1, itemParam1, itemParam2, ...
....item2, itemParam1, itemParam2, ...
scale 2, scaleParam2, scaleParam2, ...
....item1, itemParam1, itemParam2, ...
....item2, itemParam1, itemParam2, ...

До сих пор я делал в основном левые соединения для личных отношений. Это один ко многим, и я просто не могу обдумать это.

Является ли это правильным соединением, можно ли это сделать с помощью подзапроса, как получить в него полные внешние строки ...

позже я бы хотел пройти через все вложенные циклы foreach.

Может быть, просто у меня болит голова ...

Ответы [ 2 ]

6 голосов
/ 10 декабря 2008

Запрос должен выглядеть примерно так:

SELECT * FROM scales
INNER JOIN items ON scales.id = items.scale_id

Если вы хотите выполнить итерацию с помощью вложенных циклов, вам нужно вытащить эти данные в массив - надеюсь, вы не откатитесь так сильно, что это израсходует слишком много памяти.

$scales = array();

while ($row = mysql_fetch_assoc($data))
{
    if (!isset($scales[$row['scale_id']]))
    {
        $row['items'] = array();
        $scales[$row['scale_id']] = $row;
    }

    $scales[$row['scale_id']]['items'][] = $row;
}

Затем вы можете выполнить цикл:

foreach ($scales as $scale)
{
    foreach ($scale['items'] as $item)
        ; //... do stuff
}

Примечание: это несколько наивно в том, что $ scale и $ item будут содержать поля из ОБА таблиц ... если это проблема, вам нужно изменить назначения в цикле выше, чтобы вытащить только те поля, которые вы хотите.

1 голос
/ 10 декабря 2008

Может быть проще сначала получить все весы, затем все предметы.

//first get scales
while ($row = fetchrowfunctionhere()) {
    $scale = $scales->createFromArray($row);
}

//then get items
$lastId = null;
while ($row = fetchrowfunctionhere()) {
    $scaleId = $row['scaleID'];
    if ($lastId != $scaleId) {
        $scale = $scales->getByScaleId($scaleId);
    }
    $item = $items->createFromArray($row);
    $scale->addItem($item);
    $lastId = $scaleId;
}

или все в одном sql

$lastId = null;
while ($row = fetchrowfunctionhere()) {
    $scaleData = array_slice($row, 0, 5, true);
    $itemData = array_slice($row, 5, 5, true);
    $scaleId = $scaleData['scaleID'];
    if ($lastId != $scaleId) {
        $scale = $scales->createFromArray($scaleData);
    }
    $item = $items->createFromArray($itemData);
    $scale->addItem($item);
    $lastId = $scaleId;
}

все как один счастливый массив

while ($row = fetchrowfunctionhere()) {
    $scaleData = array_slice($row, 0, 5, true);
    $itemData = array_slice($row, 5, 5, true);
    $scaleId = $scaleData['scaleID'];
    if (!isset($scales[$scaleId])) {
        $scales[$scaleId] = $scaleData;
    }
    $itemId = $itemData['itemID'];
    $scales[$scaleId]['items'][$itemId] = $itemData;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...