Reputation: 392
I am trying to rank users on my system based on the user's totalArticleViews and the user's totalArticles on my system. The ranking should be based on the formula (totalArticleViews + ( totalArticles * 500 )) / 100
I have a system that allows users to post articles, a record is created every time any of these articles are read by anyone. My database has the following tables. users
, articles
, reads
.
I have tried to get the views to insert into the formula, but i'm having issues getting all the users articles and multiplying it by 500 to insert into the formula to rank them all
with article_views AS (
SELECT article_id, COUNT(reads.id) AS views, 1 * 500 AS points
FROM reads
WHERE article_id IN (
SELECT id FROM articles WHERE articles.published_on IS NOT NULL AND
articles.deleted_at IS NULL
)
GROUP BY article_id
),
published AS (
SELECT COUNT(articles.id) AS TotalArticle, COUNT(articles.id) * 500 AS
points
FROM articles
WHERE published_on IS NOT NULL AND deleted_at IS NULL
GROUP BY articles.user_id
)
SELECT
users.id AS user_id,
ROUND((SUM(article_views.views) + () ) / 100.0, 2) AS points,
ROW_NUMBER() OVER (ORDER BY ROUND((SUM(article_views.views) + ()) /
100.0, 2) DESC)
FROM users
LEFT JOIN articles ON users.id = articles.user_id
LEFT JOIN reads ON articles.id = reads.article_id
LEFT JOIN article_views ON reads.article_id = article_views.article_id
WHERE
users.id IN (SELECT user_id FROM role_user WHERE role_id = 2)
AND status = 'ACTIVE'
GROUP BY users.id
ORDER BY points DESC NULLS LAST
I'm stuck at this point
(SUM(article_views.views) + () ) / 100.0, 2)
Upvotes: 1
Views: 569
Reputation: 107697
Simply use the published CTE by including the GROUP BY
column user_id in SELECT
and then joining published to users by this field in main level query.
WITH article_views AS (
SELECT r.article_id,
COUNT(r.id) AS views,
1 * 500 AS points
FROM reads r
WHERE r.article_id IN (
SELECT id
FROM articles a
WHERE a.published_on IS NOT NULL
AND a.deleted_at IS NULL
)
GROUP BY r.article_id
),
published AS (
SELECT a.user_id,
COUNT(a.id) AS TotalArticle,
COUNT(a.id) * 500 AS points
FROM articles a
WHERE a.published_on IS NOT NULL
AND a.deleted_at IS NULL
GROUP BY a.user_id
)
SELECT u.id AS user_id,
ROUND((SUM(av.views) + (p.TotalArticle)) / 100.0, 2) AS points,
ROW_NUMBER() OVER (ORDER BY ROUND((SUM(av.views) + (p.points))
/ 100.0, 2) DESC) AS rn
FROM users u
LEFT JOIN articles a ON u.id = a.user_id
LEFT JOIN reads r ON a.id = r.article_id
LEFT JOIN article_views av ON r.article_id = av.article_id
LEFT JOIN published p ON u.id = p.user_id
WHERE u.id IN (
SELECT user_id FROM role_user WHERE role_id = 2
)
AND u.status = 'ACTIVE'
GROUP BY u.id
ORDER BY points DESC NULLS LAST
Upvotes: 2