Сложный mysql запрос need help

Тема в разделе "PHP", создана пользователем phillip, 21 ноя 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. phillip

    phillip

    Регистр.:
    4 сен 2007
    Сообщения:
    413
    Симпатии:
    15
    Ребята, помогите плиз сижу туплю!!

    Три таблицы.
    Первая- Отели.
    Вторая- Комнаты в отелях. (В одном отеле может быть много комнат)
    Третья таблица- Цены на комнаты (На каждую комнату могут быть разные цены, допустим в будни одна, в выходные- другая)

    Мне необходимо собрать в массив все отели, в отелях все комнаты, у комнат все цены.
    Не знаю как объяснить, ну чтоб массив был и я в браузер красиво вывел-
    Гостиница "Космос", комнаты: Люкс (15р в субботу, 20р в пятницу, 25р на новый год), Полулюкс (10р в субботу, 10р в пятницу, 15р на новый год)
    Гостиница "Москва", комнаты: Люкс (15р в субботу, 20р в пятницу, 25р на новый год), Полулюкс (10р в субботу, 10р в пятницу, 15р на новый год)
     
  2. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    Чтобы выглядело красиво, одним запросом такой ответ получить неполучится, ибо ответ в любом случае придет в виде таблицы, а значит названия отелей и комнат будут дублироваться.
     
  3. phillip

    phillip

    Регистр.:
    4 сен 2007
    Сообщения:
    413
    Симпатии:
    15
    значит надо делать вложенные запросы получается, напрягая сильно бд, а потом составлять красивую хтмл страницу для вывода в браузер, и кешировать ее, для того чтобы часто так не напрягать бд, да?
     
  4. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    Если проект не высоконагруженный, бд не будет напрягаться. В противном случае стоит подумать о переходе на memcache
     
  5. Phrack

    Phrack

    Регистр.:
    3 ноя 2010
    Сообщения:
    264
    Симпатии:
    38
    позволю себе вопрос в чужой теме..
    Поскольку такие запросы достаточно часто встречаются (точнее такой вид связей table - one to many - table - many to one - table), то что считают высоконагруженным проектом(сколько запросов в час)?
     
  6. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    четкого определения и стандартов высокогонагруженного проекта нет. А нагруженность определяется количеством запросов в единицу времени. Так что каждый для себя решает высоконагруженный это проект или нет.
     
  7. Maza

    Maza

    Регистр.:
    3 июл 2007
    Сообщения:
    255
    Симпатии:
    118
    Сделай хранимую процедуру ввиде цикла в которую входят представления и джойни представения между собой.
     
    phillip нравится это.
  8. polyetilen

    polyetilen Заблокирован

    Регистр.:
    10 авг 2006
    Сообщения:
    814
    Симпатии:
    474
    вариант с вложенным запросом, запрашиваем список отелей и вложенным запросом ещё получаем комнаты и цены
    Код:
    SELECT CONCAT(o.title, ", комнаты: ", GROUP_CONCAT(k.info)) oteli
    FROM o,
    (
        SELECT k.o_id, CONCAT(k.title, " (", GROUP_CONCAT(c.price SEPARATOR ", "), ")") info
        FROM k
        LEFT JOIN c ON c.k_id=k.id
        GROUP BY k.id
    ) k
    WHERE o.id=k.o_id
    GROUP BY o.id
    ORDER BY o.title
    
    база в три таблицы
    Код:
    CREATE TABLE IF NOT EXISTS `c` (
      `id` int(11) NOT NULL auto_increment,
      `k_id` int(11) NOT NULL,
      `price` varchar(255) NOT NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=13 ;
    
    
    INSERT INTO `c` (`id`, `k_id`, `price`) VALUES
    (1, 1, '15р в субботу'),
    (2, 1, '20р в пятницу'),
    (3, 1, '25р на новый год'),
    (4, 2, '10р в субботу'),
    (5, 2, '10р в пятницу'),
    (6, 2, '15р на новый год'),
    (7, 3, '15р в субботу'),
    (8, 3, '20р в пятницу'),
    (9, 3, '25р на новый год'),
    (10, 4, '10р в субботу'),
    (11, 4, '10р в пятницу'),
    (12, 4, '15р на новый год');
    
    
    CREATE TABLE IF NOT EXISTS `k` (
      `id` int(11) NOT NULL auto_increment,
      `o_id` int(11) NOT NULL,
      `title` varchar(255) NOT NULL,
      PRIMARY KEY  (`id`),
      KEY `o_id` (`o_id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
    
    
    INSERT INTO `k` (`id`, `o_id`, `title`) VALUES
    (1, 1, 'Люкс'),
    (2, 1, 'Полулюкс'),
    (3, 2, 'Люкс'),
    (4, 2, 'Полулюкс');
    
    
    CREATE TABLE IF NOT EXISTS `o` (
      `id` int(11) NOT NULL auto_increment,
      `title` varchar(255) NOT NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
    
    
    INSERT INTO `o` (`id`, `title`) VALUES
    (1, 'Гостиница "Космос"'),
    (2, 'Гостиница "Москва"');
    
    
    
     
    phillip нравится это.
  9. SiZE

    SiZE Постоялец

    Регистр.:
    31 янв 2010
    Сообщения:
    51
    Симпатии:
    10
    PHP:
    $query mysql_query("SELECT
    *
    FROM
     hotels h
     LEFT JOIN rooms r ON( r.hotel_id=h_id )
     LEFT JOIN prices p ON( p.room_id=r_id )
    ORDER BY
     hotel_name, // Имя отеля
     room_name, // Имя комнаты
     price_week_day // День недели
    "
    );
    $arr = array();
    $prev_hotel_id 0;
    while ( 
    $r mysql_fetch_array$query ) ) {
     if ( 
    $prev_hotel_id != $r['hotel_id'] ) {
      
    $prev_hotel_id $r['hotel_id'];
      
    $arr['hotels'][ $r['hotel_id'] ]['name'] = $r['hotel_name'];
      
    $arr['hotels'][ $r['hotel_id'] ]['rooms'] = array();
     }
     
    // ...далее сам додумай, как сформируешь массив красивый
    // - комменатрии в MySQL не забудь убрать или заменить на /**/
     
    phillip нравится это.
  10. Phrack

    Phrack

    Регистр.:
    3 ноя 2010
    Сообщения:
    264
    Симпатии:
    38
    Рекомендую ознакомиться с данным материалом
    http://blogs.sitepoint.com/2010/11/19/mysql-mistakes-php-developers/

    дабы не писать таких запросов (обратите внимание на пункт 2). А вобще надо переходить на фреймворки.
     
    phillip нравится это.
Статус темы:
Закрыта.