I have a tables called pages, page_views, page_items and page_votes. The latter three tables contain a
This will select TOP 10 viewed
pages, and will count items and votes only for these pages.
Efficient if you have lots of pages but need only 10
of them, eliminates unneeded counting.
SELECT (
SELECT COUNT(*)
FROM page_views
WHERE page_views.page_id = pages.id
) AS views_count,
(
SELECT COUNT(*)
FROM page_items
WHERE page_items.page_id = pages.id
) AS items_count,
COALESCE(
(
SELECT SUM(vote)
FROM page_votes
WHERE page_votes.page_id = pages.id
), 0) AS votes_sum
FROM pages
ORDER BY
views_count DESC
LIMIT 10
Even more efficient query:
SELECT pages.*,
(
SELECT COUNT(*)
FROM page_items
WHERE page_items.page_id = pages.id
) AS items_count,
COALESCE(
(
SELECT SUM(vote)
FROM page_votes
WHERE page_votes.page_id = pages.id
), 0) AS votes_sum
FROM (
SELECT page_id, COUNT(*) AS cnt
FROM page_views
GROUP BY
page_id
ORDER BY cnt DESC
LIMIT 10
) AS pvd,
pages
WHERE pages.id = pvd.page_id
, eliminates unneeded joins with pages
.
Assuming I read your SQL correctly and you want the top 10 pages by views, try this:
SELECT p.*,
(SELECT SUM(views) FROM page_views WHERE page_id = p.page_id) views,
(SELECT SUM(votes) FROM page_votes WHERE page_id = p.page_id) votes,
(SELECT SUM(items) FROM page_items WHERE page_id = p.page_id) items
FROM pages p
ORDER BY views DESC
LIMIT 10