вложенный цикл while mysql_fetch_array

У меня есть набор вложенных циклов while для сравнения запросов mysql друг с другом. Вот код:

while($row = mysql_fetch_array($resultbat))
{
    $drafted = 0;

while($crossedRow = mysql_fetch_array($crossedAnswer))
{

    if($row['NAME'] == $crossedRow['name'])
    {
        $drafted = 1;
    }
    else
    {
        $drafted = 0;
    }
}
if ($drafted == 1)
{
    echo "<tr class='drafted' id='" . $row['NAME'] . "'>";
}
else if($n&1)
{
    echo "<tr id='" . $row['NAME'] . "'>";
}else
{
    echo "<tr class='alt' id='" . $row['NAME'] . "'>";
}

...}

В $resultbat находится список всех игроков, а в $crossedAnswer — список нескольких игроков, которых следует отметить. Для каждого игрока я хочу узнать, есть ли он в списке игроков $crossedAnswer. Если они есть, я хочу пометить класс этого html-элемента как черновой.

Заранее спасибо.


person rodzilla    schedule 15.01.2013    source источник
comment
Не используйте mysql_* функции в новом коде. Они больше не поддерживаются и официально объявлены устаревшими. Видите красное поле? Узнайте о подготовленных операторах и используйте PDO или MySQLэта статья поможет вам определиться. Если вы выберете PDO, вот хороший учебник.   -  person Kermit    schedule 16.01.2013


Ответы (1)


Я думаю, вам нужно либо:

  • открыть курсор на $crossedAnswer для каждой строки из $resultbat (открыть его в начале каждого цикла и закрыть в конце, что эффективно запускает этот запрос для каждого for в resultbat) или

  • извлечь все строки из набора результатов $crossedAnswer в структуру и просмотреть эту структуру для каждой строки из $resultbat (чтобы избежать многократного запуска одного и того же запроса к базе данных) или

  • убедитесь, что $resultbat и $crossedAnswer упорядочены по значению ключа, и выполните только один цикл; откройте оба курсора, извлеките строку из каждого, а затем сравните значения ключей, чтобы определить, какой набор результатов «отстает», а из какого извлекать (это более эффективно, но это более сложный код для написания и тестирования), или

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


Лично я бы выбрал последнее. Я бы позволил MySQL выполнить соединение, получить один набор результатов и один цикл.

Запрос для получения набора результатов будет иметь форму:

SELECT b.*
     , IF(a.name IS NOT NULL,1,0) AS drafted
  FROM (
         query_for_$resultbat
       ) b
  LEFT
  JOIN (
         query_for_$crossedAnswer
       ) a
    ON b.name = a.name

Обратите внимание, что если соответствующая строка найдена в a, то столбец drafted вернет 1, в противном случае он вернет 0.


Код для обработки этого набора результатов, основанный на исходном коде, может быть примерно таким:

while($row = mysql_fetch_array($result))
{
    $class = "";
    if($row['drafted'] == 1
    {
        $class = "class='drafted' ";
    }
    else if($n&1)
    {
        $class = "";
    }
    else
    {
        $class = "class='alt' ";
    }

    echo "<tr " . $class . " id='" . $row['NAME'] . "'>";
    ...
}
person spencer7593    schedule 15.01.2013
comment
Как мне получить все строки из $crossedAnswer в структуру? Не могли бы вы привести пример этого? - person rodzilla; 16.01.2013
comment
Я понимаю концепцию объединения, но мне нужно распечатать всех игроков из $resultbat и просто изменить класс для конкретных игроков, которые находятся в результате $crossedAnswer. Если я сделаю соединение, чтобы просто дать мне игроков, которые находятся в обеих таблицах, я не смогу распечатать всех игроков. - person rodzilla; 16.01.2013
comment
@ user1956847: ВНЕШНЕЕ СОЕДИНЕНИЕ делает именно то, что вам нужно, оно возвращает ВСЕ строки из одной таблицы (или запроса) вместе с любыми соответствующими строками (если есть) из другой таблицы (или запроса). В вашем случае набор результатов должен включать столбец, который указывал бы, был ли игрок найден в обеих таблицах или нет. Как правило, выполнение одного запроса для получения необходимого набора результатов более эффективно, чем выполнение двух (или более) запросов и развертывание собственной операции внешнего соединения. - person spencer7593; 16.01.2013