Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Многотабличный запрос
 
 автор: Archimonde*   (02.12.2007 в 18:28)   письмо автору
 
 

Есть две таблицы - разделы каталога (section_id, имя и т.д.) и сайты каталога (site_id, section_id и т.д.)
Так вот нужно достать список разделов каталога с количеством сайтов в каждом из них. То есть нужно подсчитать кол-во записей с соответстующим section_id из таблицы сайтов каталога.
Можно запросить список разделов и при выводе в цикле каждый раз делать запрос на подсчет количества сайтов. Но мне не нравится такой подход :( Хотелось бы одним запросом...
Не подскажите как это можно сделать?

Добавлено чуть позже:
Попробовал сам составить запрос:
SELECT `cat_sections`.* , COUNT( `cat_sites`.`site_id`) AS `qty` 
FROM `cat_sections` 
LEFT JOIN (`cat_sites` ) ON ( `cat_sites`.`section_id` = `cat_sections`.`section_id` ) 
GROUP BY `cat_sections`.`section_id` 
ORDER BY `cat_sections`.`section_id` ASC;


Можно сделать лучше (оптимизировать, например)?

   
 
 автор: Trianon   (02.12.2007 в 23:21)   письмо автору
 
   для: Archimonde*   (02.12.2007 в 18:28)
 

Я бы написал так.

Чтобы получить данные о количестве сайтов в секциях:

SELECT  `cat_sections`.`section_id` , COUNT( `cat_sites`.`site_id`) AS `qty` 
  FROM `cat_sections` 
    LEFT JOIN `cat_sites`  ON  `cat_sites`.`section_id` = `cat_sections`.`section_id`  
  GROUP BY `cat_sections`.`section_id` 

имеем в итоге два столбика - номер секции и число сайтов.

Добавлять в список select что либо отличное от агрегатных функций [то есть COUNT( `cat_sites`.`site_id`)] и полей, перечисленных в GROUP BY [то есть `cat_sections`.`section_id` ] согласно правилам языка SQL недопустимо, поскольку вызывает неоднозначность.
Чтобы добавить остальные столбцы таблицы секций, придется применить еще один JOIN:

SELECT `cat_sections`.* 
  FROM `cat_sections` 
  JOIN (
    SELECT  `cat_sections`.`section_id` , COUNT( `cat_sites`.`site_id`) AS `qty` 
      FROM `cat_sections` 
        LEFT JOIN `cat_sites`  ON  `cat_sites`.`section_id` = `cat_sections`.`section_id`  
      GROUP BY `cat_sections`.`section_id` 
  ) AS `qty_tab` ON `cat_sections` .`section_id` = `qty_tab`.`section_id`
ORDER BY `cat_sections`.`section_name` ASC

   
 
 автор: Archimonde*   (03.12.2007 в 00:44)   письмо автору
 
   для: Trianon   (02.12.2007 в 23:21)
 

>Добавлять в список select что либо отличное от агрегатных функций [то есть COUNT( `cat_sites`.`site_id`)] и полей, перечисленных в GROUP BY [то есть `cat_sections`.`section_id` ] согласно правилам языка SQL недопустимо, поскольку вызывает неоднозначность.

Недопустимо в смысле нежелательно или имеется ввиду в стандарте SQL запрещено, но MySQL позволяет? Мой запрос просто выполнился нормально.

А во втором запросе, я думаю, нужно заменить "SELECT `cat_sections`.*" (в самом начале) на "SELECT `cat_sections` ". В противном случае стобики из qty_tab не добавляются в результат.

   
 
 автор: Trianon   (03.12.2007 в 01:08)   письмо автору
 
   для: Archimonde*   (03.12.2007 в 00:44)
 

>Недопустимо в смысле нежелательно или имеется ввиду в стандарте SQL запрещено, но MySQL позволяет?
>Мой запрос просто выполнился нормально.

В смысле - запрещено стандартом. MySQL на это закрывает глаза.
На самом деле, в данном случае, когда группирование выполняется по первичному ключу, а значит все остальные поля `cat_sections`.* будут жестко определены без неоднозначности, на этот огрех и вправду можно закрыть глаза.
Но лично я стараюсь так не писать.

>А во втором запросе, я думаю, нужно заменить "SELECT `cat_sections`.*" (в самом начале) на "SELECT `cat_sections` ".
>В противном случае стобики из qty_tab не добавляются в результат.

Да, конечно. Правильно будет SELECT `cat_sections`.* , `qty_tab`.`qty` во внешнем запросе.

   
 
 автор: Archimonde*   (03.12.2007 в 01:18)   письмо автору
 
   для: Trianon   (03.12.2007 в 01:08)
 

Всё ясно. Большое спасибо.

   
 
 автор: Archimonde*   (08.12.2007 в 20:46)   письмо автору
 
   для: Trianon   (03.12.2007 в 01:08)
 

Кстати, еще один вопрос появился. А если мне нужно составить условие для выборки сайтов (допустим, чтобы не считать заблокированных), то как это лучше сделать?
Я вот пока только заменил JOIN на LEFT JOIN во внешнем запросе и при получении числа сайтов привожу это число к integer (если по условию я не получаю ни одного сайта, то вместо числа получается пустая строка).

   
 
 автор: Trianon   (08.12.2007 в 22:00)   письмо автору
 
   для: Archimonde*   (08.12.2007 в 20:46)
 

LEFT JOIN `cat_sites` ON `cat_sites`.`section_id` = `cat_sections`.`section_id` AND NOT `cat_sites`.locked

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования