Reputation: 1108
I'm trying to build a query that retrieves me, for each post, its respective count of images, comments, likes and favorites. All this data is in separate relational tables that allways store the id of the post.
However when I run the query 3 other pages come with exactly the same data as the first page.
So far I've coded this
SELECT * FROM
(SELECT pst.* FROM posts as pst
LEFT JOIN postcategories as pstcat
ON pst.id = pstcat.id_post
WHERE pst.date IS NOT NULL AND pst.date >= '2013-01-01 00:00:00' AND pst.date <= '2013-01-11 00:00:00' ) as res1
INNER JOIN
(SELECT pst.*, count(pstcmt.id) as cmtCount
FROM posts as pst
LEFT JOIN userpostcomments as pstcmt
ON pst.id = pstcmt.id_post
GROUP BY pst.id) as res2 ON res1.id = res2.id
INNER JOIN
(SELECT pst.id, count(pstlk.id) as lkCount
FROM posts as pst
LEFT JOIN userpostlikes as pstlk
ON pst.id = pstlk.id_post
GROUP BY pst.id) as res3 ON res1.id = res3.id
INNER JOIN
(SELECT pst.id, count(pstfav.id) as favCount
FROM posts as pst
LEFT JOIN userpostfavorites as pstfav
ON pst.id = pstfav.id_post
GROUP BY pst.id) as res4 ON res1.id = res4.id
INNER JOIN
(SELECT pst.id, count(pstimg.id) as imgCount
FROM posts as pst
LEFT JOIN postimages as pstimg
ON pst.id = pstimg.id_post
GROUP BY pst.id) as res5 ON res1.id = res5.id
WHERE res1.deleted = 0
AND res1.date IS NOT NULL
GROUP BY res1.id
ORDER BY res1.date DESC
Thank you
UPDATE : Updated query with ORDER BY as sugested. However the problem of data mirroring still exists
Upvotes: 0
Views: 609
Reputation: 33381
Maybe, this is what you want:
SELECT pst.id,
COALESCE(cmtCount, 0) cmtCount,
COALESCE(lkCount, 0) lkCount,
COALESCE(pstfavCount, 0) pstfavCount,
COALESCE(imgCount , 0) imgCount,
FROM posts as pst
LEFT JOIN
(SELECT id_post, count(id) as cmtCount
FROM userpostcomments GROUP BY id_post) as cmt
ON pst.id = cmt.id_post
LEFT JOIN
(SELECT id_post, count(id) as lkCount
FROM userpostlikes GROUP BY id_post) as lk
ON pst.id = lk.id_post
LEFT JOIN
(SELECT id_post, count(id) as pstfavCount
FROM userpostfavorites GROUP BY id_post) as pstfav
ON pst.id = pstfav.id_post
LEFT JOIN
(SELECT id_post, count(id) as imgCount
FROM postimages GROUP BY id_post) as img
ON pst.id = img.id_post
WHERE pst.deleted = 0
AND pst.date >= '2013-01-01 00:00:00'
AND pst.date <= '2013-01-11 00:00:00'
ORDER BY pst.date DESC
I think, this query more faster.
SELECT pst.id,
COUNT(DISTINCT cmt.id) cmtCount,
COUNT(DISTINCT lk.id) lkCount,
COUNT(DISTINCT pstfav.id) pstfavCount,
COUNT(DISTINCT img.id) imgCount,
FROM posts as pst
LEFT JOIN userpostcomments cmt
ON pst.id = cmt.id_post
LEFT JOIN userpostlikes lk
ON pst.id = lk.id_post
LEFT JOIN userpostfavorites pstfav
ON pst.id = pstfav.id_post
LEFT JOIN postimages img
ON pst.id = img.id_post
WHERE pst.deleted = 0
AND pst.date >= '2013-01-01 00:00:00'
AND pst.date <= '2013-01-11 00:00:00'
GROUP BY pst.id
ORDER BY pst.date DESC
Upvotes: 2