Простейший SQL-запрос ... но не работает не так как должен

_savit
На сайте с 19.03.2006
Offline
135
701

Всем привет.

Итак, есть 2 таблицы: каталог (catalog) и статьи (articles)

для простоты так:

таблица catalog:

cat_id int unsigned auto_increment primary key

cat_name char(75)

таблица articles:

art_id int unsigned auto_increment primary key

art_text text

art_catid int unsigned

Стоит элементарная задача вывода разделов каталога и в скобочках сколько в каждом разделе статей

запрос:

SELECT cat_name, COUNT(art_catid) AS counter1 FROM catalog AS c LEFT JOIN articles AS a ON c.cat_id=a.art_catid GROUP BY a.art_catid

дак вот как ни странно такой запрос возвращает мне информацию только о тех разделах каталога в которых есть хотя бы одна статья и только один раздел в котором 0 статей ( хотя таких разелов в которых нет статей много )

толи два часа ночи сказываются, толи я старый стал, толи мускуль на хостинге глючт .. :confused:

https://vk-botovod.ru - комбайн ВКонтакте, мультимессенджер, эмулятор жизни аккаунтов
progress
На сайте с 11.07.2006
Offline
125
#1

Все правильно он возвращает. Сделайте проще:

SELECT cat_name, (SELECT COUNT(*) FROM `articles` WHERE `articles`.`art_catid` = `catalog`.`cat_id`) AS counter1 FROM `catalog`

edogs software
На сайте с 15.12.2005
Offline
775
#2
progress:
Все правильно он возвращает. Сделайте проще:
SELECT cat_name, (SELECT COUNT(*) FROM `articles` WHERE `articles`.`art_catid` = `catalog`.`cat_id`) AS counter1 FROM `catalog`

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

_savit:
Всем привет.

Итак, есть 2 таблицы: каталог (catalog) и статьи (articles)

для простоты так:

таблица catalog:
cat_id int unsigned auto_increment primary key
cat_name char(75)

таблица articles:
art_id int unsigned auto_increment primary key
art_text text
art_catid int unsigned

Стоит элементарная задача вывода разделов каталога и в скобочках сколько в каждом разделе статей

запрос:

SELECT cat_name, COUNT(art_catid) AS counter1 FROM catalog AS c LEFT JOIN articles AS a ON c.cat_id=a.art_catid GROUP BY a.art_catid

дак вот как ни странно такой запрос возвращает мне информацию только о тех разделах каталога в которых есть хотя бы одна статья и только один раздел в котором 0 статей ( хотя таких разелов в которых нет статей много )

толи два часа ночи сказываются, толи я старый стал, толи мускуль на хостинге глючт .. 😕

Дык всё логично. Вы группируете по a.art_catid . Оно у Вас есть только в том случае, если в таблице (а) - таблице статей - есть статья. В другом случае это null... как следствие выводится один раздел с 0 статей, потому что что для всех разделов с нулем статей в этом поле окажется null и именно в эту "группу" все разделы с нулем статей и сгруппируются.

Группируйте по c.cat_id и всё.

Разработка крупных и средних проектов. Можно с криптой. Разумные цены. Хорошее качество. Адекватный подход. Продаем lenovo legion в спб, дешевле магазинов, новые, запечатанные. Есть разные. skype: edogssoft
_savit
На сайте с 19.03.2006
Offline
135
#3
progress:
Все правильно он возвращает. Сделайте проще:
SELECT cat_name, (SELECT COUNT(*) FROM `articles` WHERE `articles`.`art_catid` = `catalog`.`cat_id`) AS counter1 FROM `catalog`

За ответ конечно спасибо, но так имхо не комильфо!

_savit добавил 28.12.2008 в 03:20

edogs:

Дык всё логично. Вы группируете по a.art_catid . Оно у Вас есть только в том случае, если в таблице (а) - таблице статей - есть статья. В другом случае это null... как следствие выводится один раздел с 0 статей, потому что что для всех разделов с нулем статей в этом поле окажется null и именно в эту "группу" все разделы с нулем статей и сгруппируются.
Группируйте по c.cat_id и всё.

Да, Вы абсолютно правы .. это я затупил на ночь глядя... ночь, пиво и программирование вещи не совместимые ж)))) Еще раз thx!

progress
На сайте с 11.07.2006
Offline
125
#4
edogs:
Использовать так вложенные запросы это сродни (не точно конечно, слегка утрируем) выборке категорий в цикле, а внутри цикла выборке кол-ва статей. В общем не гуд если хоть немного беспокоит нагрузка на базу, хотя если гнаться за простотой...

Дык всё логично. Вы группируете по a.art_catid . Оно у Вас есть только в том случае, если в таблице (а) - таблице статей - есть статья. В другом случае это null... как следствие выводится один раздел с 0 статей, потому что что для всех разделов с нулем статей в этом поле окажется null и именно в эту "группу" все разделы с нулем статей и сгруппируются.
Группируйте по c.cat_id и всё.

Если рассуждать про циклы, то объединение идет темже путем. Возможно, вы и правы, но проведя десятки экспериментов с таблицами с миллионами записей я пришел к интересному результату, что вложенный запрос отрабатывал быстрее. Конечно, все зависит от структуры таблиц и самого запроса, но на простейшем примере как здесь вложенный запрос отрабатывал быстрее.

N
На сайте с 06.05.2007
Offline
419
#5

в этом запросе очень даже реально что подзапрос обгонит объединение.

если категорий немного, есть индекс по art_catid, count(*) может довольно шустро получить общее число строк даже не считывая индекс глубоко, в то время как join будет строить временные таблицы и запихивать туда значения в цикле и группировать.

netwind добавил 29.12.2008 в 22:47

нее наврал. меньше никак не получается. все-таки очень редкие запросы должны быть что подзапрос был быстрее

Кнопка вызова админа ()

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий