Здравствуйте, есть код примерно следующего характера: PHP: <?php $result1 = $db->query ('SELECT product_id FROM group WHERE client_id = 1;'); $num_rows1 = $db->num_rows ($result1); for ($i = 0; $i < $num_rows1; $i++) { $row1 = $db->fetch_array ($result1); $result2 = $db->query ('SELECT update_id FROM update WHERE product_id = ' . $row1['product_id'] . ';'); $num_rows2 = $db->num_rows ($result2); for ($j = 0; $j < $num_rows2; $j++) { $row2 = $db->fetch_array ($result2) // } } ?> var_dump: PHP: <?php var_dump ($row1['product_id']); ?> возвращает только первое значение, все остальные нулы. Если не использую класс, а создаю коннект к базе и второй запрос кручу через этот коннект, то все нормально... В какую сторону смотреть, что не так?
Структура базы кривая (не моя), поэтому одним запросом сделать это не реально, по крайней, мере я так думаю. Я имею идентификатор пользователя, по которому выбираю продукты, которые он приобрел, если для продукта есть обновления, то вывожу их, потом следующий продукт. Раньше в скрипте прописывалось подключение к базе, теперь, когда подключил класс для mysql, то вылазит эта лажа, вот я и думаю, что вероятно дело в классе (сам писал), возможно что-то не учел, но хз куда смотреть, могу код класса показать, если нужно. P.S. Мой 100-й пост на форуме
я не спец в запросах, но сделать выборку такую как ты описал не проблема. left join кажется как раз тут очень кстати Mr. T Сообщения: 104 быстро ты
Ок, структура: Таблица products: - product_id - product_name - client_id Таблица upgrades: - upgrade_id - upgrade_name - product_id Задача: Зная client_id, выбрать все продукты, которые он купил из таблицы products, если для продукта есть обновления в таблице upgrades, то вывести их, потом перейти сразу к следующему продукту и повторить проверку наличия обновления в таблице upgrades. Как я делаю: Выбираю все product_id, которые завязаны за выбранным client_id, значения product_id передаю в цикле в другой запрос и вывожу обновления. Как здесь через left join делать, не пойму как потом "размотать" данные... Может быть, дело в классе моем?
1) Есть подозрение, что пофетчить два результата на одном коннекте нельзя. Точнее у меня не получалось - возникали конфликты. 2) [sql]select product_name, upgrade_name from products as p left outer join upgrades as u on p.product_id=u.product_id where client_id=1 order by product_name[/sql] Если для каждого продукта есть не более одного обновления все работает. Если для одного продукта может быть несколько обновлений, то можно замутить цикл типа: PHP: <?php echo "<div class='products'>Ваши продукты"; $rez=$db->select($sql); $lastProduct=''; while ($row=$db->fetchAssoc($rez)){ if($lastProduct!=$row['product_name']){ $lastProduct=$row['product_name']; echo "</div>"; echo "<div class='prod'>"; echo "<p class='productName'>".$row['product_name']."</p>"; } if($row['upgrade_name']){ echo "<p class='upgrade'>".$row['product_name']."</p>"; } } echo "</div>";
Для продукта может быть более одного обновления и часто так и есть, про mysql_fetch_array на одном коннекте уже тоже странности замечал. Приведенный пример относиться к приведенному запросу? Просто не понял его суть, если юзать left join, то слева будет дублироваться id продукта, в таком случае можно завести дополнительный счетчик и проверять id продукта, пока не встретиться следующий, но как-то стремно алгоритм выглядит...
Да. В выборке ничего не дублируется, там выбирается ровно 2 поля: имя продукта и имя обновления. Именно так и сделано. Согласен, но пока я не знаю как лучше можно разобрать подобные запросы.
Спасибо за наводку, испробую. С другой стороны, один цикл, один запрос, возможно быстрее будет работать, но нужно замерять время.
Volt(220), предложенный вариант реально рулит, но возникла маленькая проблема, не могу вкурить как лучше сделать. К примеру, код: PHP: <?php $result = $db->query ('SQL-запрос'); $num_rows = $db->num_rows ($result); $last_product_id = ''; for ($i = 0; $i < $num_rows; $i++) { $row = $db->fetch_array ($result); list ($product_id, $product_name, $expiration_date, $upgrade_id, $upgrade_name) = $row; if ($last_product_id != $product_id) { $last_product_id = $product_id; $date = date ('Y-m-d'); echo '<table>' . "\r\n"; if ($date > $expiration_date) { echo ' <tr>' . "\r\n"; echo ' <td>Срок обслуживания закончился!</td>' . "\r\n"; echo ' </tr>' . "\r\n"; } else { echo ' <tr>' . "\r\n"; echo ' <td>' . $product_name . '</td>' . "\r\n"; echo ' </tr>' . "\r\n"; } } if ($upgrade_id != '') { if ($date < $expiration_date) { echo ' <tr>' . "\r\n"; echo ' <td>' . $upgrade_name . '</td>' . "\r\n"; echo ' </tr>' . "\r\n"; } } } ?> Все хорошо, но есть одно но. Каждый продукт вместе с обновлениями выводится в одной таблице, проблема с закрывающимся тегом </table>. Шаманил, но так и не понял, как организовать проверку, чтобы вывести его. Прошу помощи
echo '<table>' . "\r\n"; выносишь до if-а, после list( echo '</table>' . "\r\n"; ставишь после последнего if-а, но до закрывающей фигурной скобки for-a
Gromo, спасибо, попробую, еще вопрос остался один, зачем в примере был заюзан left join? думал, думал, но так и не понял, нуллов вроде нет в таблице.
1) Код (Text): if ($upgrade_id != '') { я бы заменил на Код (Text): if ($upgrade_id) { 2) Закрывающий </table> надо выводить после $last_product_id = $product_id; Теперь реши как НЕ выводить закрывающий </table> в первый раз. =) Gromo Хрен! Тогда обновления не будут в той же таблице что и продукт от них. =))