Сложный запрос SQL


Dram
197

Есть таблица отзывов про организации, про них юзеры пишут отзывы и голосуют, у каждого отзыва сохраняется кол-во звезд которые юзер поставил фирме от 1 до 5.

Хочу запросом вывести кол-во отзывов — положительных, отрицательных и нейтральных. Ничего умнее чем дважды сджойнить эту же таблицу не придумал (может есть разумнее ход?)

В итоге получился такой запрос

SELECT COUNT(t1.id)as bad,COUNT(t2.id)as neutrally,COUNT(t3.id)as good  
FROM `comments_items` as t1 
INNER JOIN `comments_items` as t2 on (t2.object_group = 'com_firm' AND t2.object_id = 1698 AND t2.rate=3)
INNER JOIN `comments_items` as t3 on (t3.object_group = 'com_firm' AND t3.object_id = 1698 AND t3.rate>3)
WHERE t1.object_group = 'com_firm' AND t1.object_id = 1698 AND t1.rate<=2

Но даже он выводит три колонки с непонятными цифрами (не теми что должны)

К примеру если посмотреть только плохие отзывы то запрос отрабатывает правильно

SELECT * FROM `comments_items` WHERE `object_group` LIKE 'com_firm' AND `object_id` = 1698 AND `rate` <= 2

Где я ошибаюсь в первом запросе?

P.S. я должен получить 60 / 1 / 199

а получаю  11940/ 11940/ 11940

т.е. 60*99*1 = 11940


divv

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


Dram

Получилось так

SELECT count(*) AS bad, 
(SELECT count(*) FROM `comments_items` WHERE `object_group` = 'com_firm' AND `object_id` = 1698 AND `rate` = 3) AS neutrally,
(SELECT count(*) FROM `comments_items` WHERE `object_group` = 'com_firm' AND `object_id` = 1698 AND `rate` > 3) AS good
FROM comments_items WHERE `object_group` = 'com_firm' AND `object_id` = 1698 AND `rate` <=2


edogs software

Первый запрос у Вас просто абсурден, связываете без связей, получаете групповые результаты без группировки, хотите получить результаты из t2,t3, но с помощью where обрезаете их по t1 (join  условия != where). По нагрузке при даже среднем количестве данных будет неадекватно.

Если скорость не особо принципиальна, то можно за одну строку

select sum(if(rate=2,1,0)) rate2, sum(if(rate=3,1,0)) rate3 , object_id from comments_items where object_group=’com_firm’  and object_id=1698 group by object_id
получите нечто вроде
60, 199, 1698

Если принципиальна и висят индексе соответствующие, то можно в несколько строк

select count(*), rate, object_id from comments_items where object_group=’com_firm’ and object_id=1698 group by object_id, rate
получите нечто вроде
60 2 1698
199 1 1698


drDaemon

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *