Как я могу скопировать таблицу базы данных в массив при учете пропущенных идентификаторов? - PullRequest
0 голосов
/ 11 января 2012

Ранее я проектировал веб-сайт, над которым я работаю, так, чтобы я просто запрашивал в базе данных необходимую мне информацию на странице, но после реализации функции, которая требовала каждую ячейку в каждой таблице на каждой странице (о боже)Я понял, что в целях оптимизации я должен объединить его в один большой запрос к базе данных и бросить каждую таблицу в массив, таким образом сокращая количество вызовов SQL.

Проблема заключается в том, что я хочу, чтобы этот массив включал пропущенные идентификаторы.(первичный ключ) в базе данных.Конечно, я постараюсь избежать пропущенных строк / идентификаторов, но я не буду управлять этими данными, и я хочу, чтобы система была достаточно умной, чтобы учитывать любые подобные проблемы.

Мой метод запускаетсядостаточно просто:

//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];

//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
    $row = mysql_fetch_assoc($localityResult);
    $localityData["id"][$i] = $row["id"];
    $localityData["name"][$i] = $row["name"];
}

//Output
for ($i=1;$i<$localityMax+1;$i++)
{
    echo $i.". ";
    echo $localityData["id"][$i]." - ";
    echo $localityData["name"][$i];
    echo "<br />\n";
}

Два примечания:

  1. Да, я, вероятно, должен переместить эту проверку $ localityMax в цикл PHP.

  2. Я намеренно пропускаю первый ключ массива.

Проблема здесь в том, что пропущенный ключ в базе данных не учитывается, поэтому он в итоге выводит вот так(образец таблицы):

  1. 1 - ток
  2. 2 - Джуно
  3. 3 - якорная стоянка
  4. 4 - Нэшвилл
  5. 7 - Чаттануга
  6. 8 - Мемфис
  7. -
  8. -

Я хочу написать «Ошибка» или NULLили что-то, когда строка не найдена, затем продолжайте, не прерывая вещи.Я обнаружил, что могу проверить, меньше ли $ i $ row [$ i], чтобы увидеть, пропущена ли строка, но я не уверен, как исправить это в этот момент.

Я могу предоставитьдополнительная информация или дамп базы данных, если это необходимо.Я просто застрял на этой проблеме часами, ничто из того, что я пробовал, не работает.Буду очень признателен за вашу помощь и общую обратную связь, если я сделаю какие-либо ужасные ошибки.Спасибо!


Редактировать: Я решил это!Сначала выполните итерацию по массиву, чтобы установить значение NULL или сообщение «Ошибка».Затем в назначениях установите $ i равным $ row ["id"] сразу после вызова mysql_fetch_assoc ().Полный код выглядит так:

//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];

//Reset
for ($i=1;$i<$localityMax+1;$i++)
{
    $localityData["id"][$i] = NULL;
    $localityData["name"][$i] = "Error";
}

//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
    $row = mysql_fetch_assoc($localityResult);
    $i = $row["id"];
    $localityData["id"][$i] = $row["id"];
    $localityData["name"][$i] = $row["name"];
}

//Output
for ($i=1;$i<$localityMax+1;$i++)
{
    echo $i.". ";
    echo $localityData["id"][$i]." - ";
    echo $localityData["name"][$i];
    echo "<br />\n";
}

Спасибо за помощь всем!

Ответы [ 2 ]

0 голосов
/ 11 января 2012

Первичные ключи должны быть уникальными в MySQL, поэтому вы можете получить максимум один возможный пустой идентификатор, поскольку MySQL не позволит вставлять дублирующиеся данные.

Если вы работали со столбцом, который не является первичным или уникальным ключом, ваш запрос должен был быть единственным, что могло бы измениться:

SELECT id, name FROM localities WHERE id != "";

или

SELECT id, name FROM localities WHERE NOT ISNULL(id);

РЕДАКТИРОВАТЬ: Создан новый ответ на основе разъяснений из ОП. Если у вас есть числовая последовательность, которую вы хотите сохранить непрерывной, и в таблице базы данных могут отсутствовать строки, вы можете использовать следующий (простой) код, чтобы получить то, что вам нужно. Используя тот же метод, ваш $i = ... может фактически быть установлен на первый идентификатор в последовательности из БД, если вы не хотите начинать с идентификатора: 1.

$result = mysql_query('SELECT id, name FROM localities ORDER BY id');

$data = array();
while ($row = mysql_fetch_assoc($result)) {
    $data[(int) $row['id']] = array(
        'id'   => $row['id'],
        'name' => $row['name'],
    );
}

// This saves a query to the database and a second for loop.
end($data); // move the internal pointer to the end of the array
$max = key($data); // fetch the key of the item the internal pointer is set to

for ($i = 1; $i < $max + 1; $i++) {
    if (!isset($data[$i])) {
        $data[$i] = array(
            'id'   => NULL,
            'name' => 'Erorr: Missing',
        );
    }

    echo "$i. {$data[$id]['id']} - {$data[$id]['name']}<br />\n";
}
0 голосов
/ 11 января 2012

После того, как вы получили $localityResult, вы можете поместить все идентификаторы в массив, затем перед echo $localityDataStuff проверьте, чтобы увидеть

if(in_array($i, $your_locality_id_array)) {
  // do your echoing
} else {
  // echo your not found message
}

Сделать $your_locality_id_array:

$locality_id_array = array();
foreach($localityResult as $locality) {
  $locality_id_array[] = $locality['id'];
}
...