Задавайте вопросы, мы ответим
Вы не зашли.
Доброго времени суток!
Имеется 4 таблицы:
reviews (id, section_id, title, content)
images (id, review_id, image)
comments (id, parent_id, type, comment)
rating (id, review_id, rating, user_ip)
Задача: выбрать последние 20 обзоров, первую фотку к ним (если есть), посчитать кол-во комментариев, среднюю оценку и отсортировать по оценке.
На данный момент у меня такой запрос (без таблицы rating):
SELECT r.id, r.title, i.image, COUNT(c.id)
FROM reviews r
LEFT JOIN images i ON r.id = i.review_id
LEFT JOIN comments c ON r.id = c.parent_id AND c.type = 2
WHERE r.section_id = 1
GROUP BY r.id
ORDER BY r.id DESC
LIMIT 0, 20
Этот запрос пока что не выбирает среднюю оценку, и на первый взгляд, вроде всё ок, НО если у обзора больше одной фотки, то кол-во комментариев перемножается на кол-во фоток.
Что я не так делаю, и почему? Помогите разобраться, плиз.
Неактивен
Вы неправильно считаете количество фоток
В качестве быстрого хака — можете считать уникальные id:
COUNT(DISTINCT c.id), а по хорошему это надо делать несколь-
кими запросами или через подзапросы.
Неактивен
Добавил подсчёт средней оценки:
SELECT r.id, r.title, i.image, COUNT(c.id) AS tot_com, AVG(ra.rating) AS rating
FROM reviews r
LEFT JOIN images i ON r.id = i.review_id
LEFT JOIN comments c ON r.id = c.parent_id AND c.type = 2
LEFT JOIN rating ra ON r.id = ra.review_id
WHERE r.section_id = 1
GROUP BY r.id
ORDER BY r.id DESC
LIMIT 0, 20
Теперь количество комментариев умножается ещё и на кол-во оценок
Я по моему кол-во картинок не считаю, а просто выбираю одну картинку.
DISTINCT кстати помог, но может есть другой вариант?
Что-то делать ещё 40 запросов на 20 строк выборки не хочется.
Неактивен
Представьте себе, как работает объединение. Если Вы добавляете новые
таблицы — Вы добавляете новые строки. Как следствие — COUNT() начи-
нает их считать тоже.
Можно
а) добавить условий, чтобы COUNT() не считал (DISTINCT)
б) не добавлять новые таблицы (или добавлять в виде подзапросов с LIMIT 1)
в) проявить смекалку и делить COUNT() на количество добавленных строк.
Последнее — достаточно нетривиальная операция, которая часто
сводится к пункту «б».
Неактивен
Не добавлять таблицы не получается, у пользователя должна быть возможность отсортировать обзоры по дате, кол-ву комментарием, средней оценке.
Такой запрос возвращает вроде правильный результат:
SELECT r.id, r.title, i.image, COUNT(DISTINCT c.id) AS tot_com, AVG(ra.rating) AS rating
FROM reviews r
LEFT JOIN images i ON r.id = i.review_id
LEFT JOIN comments c ON r.id = c.parent_id AND c.type = 2
LEFT JOIN rating ra ON r.id = ra.review_id
WHERE r.section_id = 1
GROUP BY r.id
ORDER BY r.id DESC
LIMIT 0, 20
А как сделать запрос с подзапросами? Я в этом совсем слаб. И будет ли он быстрее чем запрос с DISTINCT?
Paulus, помогите пожалуйста с подзапросами.
Неактивен
Просто вместо объединения делаете подзапрос:
SELECT ... , (SELECT COUNT(*) FROM comments WHERE parent_id = reviews.id) AS comment_count
FROM reviews
Что лучше — сказать сложно, я DISTINCT недолюбливаю из-за того, что он
очень умный, а умную технику я побаиваюсь
Неактивен