|
|
|
| Есть две таблицы - разделы каталога (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;
|
Можно сделать лучше (оптимизировать, например)? | |
|
|
|
|
|
|
|
для: 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
|
| |
|
|
|
|
|
|
|
для: 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 не добавляются в результат. | |
|
|
|
|
|
|
|
для: 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` во внешнем запросе. | |
|
|
|
|
|
|
|
для: Trianon
(03.12.2007 в 01:08)
| | Всё ясно. Большое спасибо. | |
|
|
|
|
|
|
|
для: Trianon
(03.12.2007 в 01:08)
| | Кстати, еще один вопрос появился. А если мне нужно составить условие для выборки сайтов (допустим, чтобы не считать заблокированных), то как это лучше сделать?
Я вот пока только заменил JOIN на LEFT JOIN во внешнем запросе и при получении числа сайтов привожу это число к integer (если по условию я не получаю ни одного сайта, то вместо числа получается пустая строка). | |
|
|
|
|
|
|
|
для: Archimonde*
(08.12.2007 в 20:46)
| | LEFT JOIN `cat_sites` ON `cat_sites`.`section_id` = `cat_sections`.`section_id` AND NOT `cat_sites`.locked | |
|
|
|