За последние 24 часа нас посетили 41713 программистов и 2583 робота. Сейчас ищут 732 программиста ...

Вывод данных при запросе типа SELECT ... INNER JOIN ... ;

Тема в разделе "PHP для новичков", создана пользователем Yadfewm, 31 май 2010.

  1. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    Допустим существует таблица `publications`(публикации) и таблица `categories` (категории сайта).
    Каждая публикация может быть размещена в нескольких категориях, для этого создана таблица `pub_cat` с записями вида:
    Код (Text):
    1.  
    2. id | pub | cat
    3. 1  | 1    |  1
    4. 2  | 1    |  2
    5. 3  | 2    |  2
    6. 4  | 2    |  3
    что означает: первая публикация отностися к категориям с id 1 и 2, вторая соответственно к 2 и 3.

    В админке сайта требуется вывести список публикаций, рядом с каждой из которых должен быть список категорий в которых она размещена.

    После запроса:
    Код (Text):
    1. SELECT `publications`.`id, ............
    2. FROM `publications`
    3. INNER JOIN `pub_cat` ON `publications`.`id` = `pub_cat`.`pub` .......
    Ответ содержит исчерпывающую информацию, но мне известен только последовательный перебор
    Код (Text):
    1. while ($row = mysql_fetch_array($result))
    в котором выводятся "дублирующие записи", и код типа
    Код (Text):
    1. $show = ($row['id'] == $lastid)?false:true;
    мне не помог ибо кто такой $lastid в первом извлеченном ряде - не известно.

    Уверен, многие сталкивались. Как выполнить правильный вывод инфы?

    Не предлагать структуры следующего вида:

    Код (Text):
    1. $query = "SELECT * FROM `publications`;"
    2. ... ... ...
    3. while ($row = mysql_fetch_array($result))
    4. {
    5.  $query = "SELECT * FROM `pub_cat` WHERE `cat` = '${row['id']}';"
    6.  ... ... ...
    7.  while ($row_cat = mysql_fetch_array($result2))
    8.  {
    9.   ....
    10.  }
    11. }
    ИМХО при выводе пятисот публикаций php скрипт создает еще стопятсот запросов, что жутко грузит скулу. :)
     
  2. karakh

    karakh Активный пользователь

    С нами с:
    11 дек 2007
    Сообщения:
    1.344
    Симпатии:
    0
    копай в сторону [sql]GROUP BY [/sql]
     
  3. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    Код (Text):
    1. SELECT `publications`.`id`, `publications`.`date`, `publications`.`heading`, `publication`.`publication`, `publication`.`category`, `categories`.`heading` AS `catname`
    2. FROM `publications`
    3. INNER JOIN `publication` ON `publications`.`id` = `publication`.`publication`
    4. INNER JOIN `categories` ON `publication`.`category` = `categories`.`id`
    5. GROUP BY `publications`.`id`
    После группировки теряются данные по категориям в которых размещена публикация (
    Пытался сделать CONCAT_WS('+', `categories`.`heading`) AS `catcat` чтобы сложить все категории в одну строчку через разделитель "+", но оказывается CONCAT_WS работает только с разными полями, а не по одному полю с GROUP BY (
     
  4. Einbaukueche

    Einbaukueche Активный пользователь

    С нами с:
    14 апр 2010
    Сообщения:
    34
    Симпатии:
    0
    Адрес:
    Там, где много гор и пива.
    Для этого есть GROUP_CONCAT.
    http://dev.mysql.com/doc/refman/5.0/en/ ... oup-concat

    Минусы - поля создаваемое таким способом ограниченно в длине (хотя для пары-тройки-десятка категорий хватит за глаза, и это настраивается, если у вас есть права на это) и этот способ относительно медленный.

    Но в принципе, если вы хотите обойтись в вашей задаче одним запросом, у вас эти 2 способа - да. Либо вы "сложите" списки категорий в одну строчку на ДБ сервере через GROUP_CONCAT и потом снова разделите её в PHP через банальный explode() итд., либо получите "квадратный" результат типа вашего первого примера и будете разбирать его уже в PHP через foreach или еще как.
     
  5. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    Только что мне подсказали об этой функции большое спасибо! :D А я сначало пытался CONCAT_WS, очень похожа, но не для этого.

    Конечно я хочу обойтись одним запросом. Можно конечно сделать просто SELECT по публикациям, а потом в самом цикле делать еще один запрос "в каких же категориях она опубликована" , но такой метод запрещен здравым смыслом :D

    Данные разнесены в разные таблицы да бы избежать "избыточности данных" или как там правильно про реляционные базы данных....

    Судя по небольшому количеству ответов на мой вопрос, программеры не очень то парятся о избыточности и о всяких теоретически правильных вещах?
     
  6. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    не, я мимо проходил прокрутил тему вниз, на посты отвечают значит все норм )ушел )
    а еше мне Luge рассказывал про http://ru.wikipedia.org/wiki/%D0%94%D0% ... 0%B8%D1%8F
    но с этим тоже переусердствовать как выяснилось не надо :D
     
  7. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    Спасибо, прочел, теперь вот думаю. Может денормализировать нафиг ))))) ? Блин, а в институте говорили "Нормализируйте, нормализируйти и еще раз..."
     
  8. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    опять двойка…

    А можно сделать два запроса и не тягать избыточные данные
    всем наплевать на данную конкретную тему, вот и всё.
     
  9. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    ММм? Два запроса? И нет запросов в цикле???

    В принципе GROUP_CONCAT помог, жаль нужно делать explode() в PHP, жаль ограничение на 1024 в GROUP_CONCAT, и жаль что нельзя чтобы список категорий был массивом, а не объединенной строчкой, как у людей чтоб...

    А что там про 2 запроса, мне очень интересно!!!
     
  10. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    http://ru2.php.net/serialize
    хз хранить ето в базе не пробовал)
    а в ini где нибудь разве не меняется?
     
  11. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    на локальном домашнем компе все меняется, на хостинге не знаю, говорят не везде