#mysql #sql
#mysql #sql
Вопрос:
Я пытаюсь написать простой запрос, который генерирует список книг, ранжированных по двум параметрам: самый последний обзор и общее количество обзоров. Чтобы вычислить самую последнюю дату рецензирования для каждой книги, я использую подзапрос и минимальную агрегатную функцию. Чтобы вычислить общее количество отзывов для каждой книги, я использую точно такой же подзапрос, но вместо него использую агрегатную функцию COUNT .
Это кажется неэффективным. Есть ли способ объединить эти подзапросы в один вызов и при этом иметь доступ к обоим агрегированным значениям в предложениях HAVING и ORDER BY запроса?
Вот псевдозапрос:
SELECT DISTINCT
(SELECT MIN(review.pub_date)
FROM review
WHERE book.id = review.book_id
AND ...
AND ...
AND ...
) AS most_recent_date,
(SELECT COUNT(review.pub_date)
FROM review
WHERE book.id = review.book_id
AND ...
AND ...
AND ...
) AS review_count,
book.id, book.pub_date, book.title, book.author
FROM book
INNER JOIN review
ON (review.book_id = book.id)
WHERE (
...
)
HAVING (most_recent_date > '$DATE')
ORDER BY review_count DESC
Я попытался объединить их в один и переместить агрегатные функции из подзапроса в предложения HAVING и ORDER BY, но я не смог получить никаких результатов таким образом.
Заранее спасибо.
Комментарии:
1. Это не имеет смысла использовать
having
, если у вас нетgroup by
предложения2. @barranka . , , Это разумный синтаксис в MySQL. Это расширение, которое позволяет использовать псевдонимы столбцов в условии.
3. @GordonLinoff этого не знал! Спасибо!
Ответ №1:
Я не думаю, что вам нужны подзапросы для этого:
select
book.id, book.pub_date, book.title, book.author,
min(review.pub_date) as most_recent_date, -- are you sure you want "min"? ("max" makes more sense to me)
count(review.pub_date) as review_count
from book
left join review on book.id = review.book_id
where ... -- Define here any conditions, including those inside the subquery
group by book.id
having most_recent_date > ?
order by review_count desc
Другой способ оптимизировать это — создать временные таблицы с желаемыми результатами, а затем перенести результаты в ваш запрос.
Комментарии:
1. Большое спасибо. Это сократило время моего запроса на 90%!
2. @HakanB. Всегда делайте это просто … обычно это лучший способ сделать что-то 😉
3. 1 . . . Но в качестве примечания: an
inner join
будет работать так же хорошо, потому что вhaving
предложении есть условие изreview
таблицы.