I have a table of posts, post_likes, and I need a query that will give me both totals for likes for posts, and also a given specific user’s likes for those posts. This means I need a good way of giving MY_USER_ID as input data.
Here’s a query that works
create view post_view as select post.id, coalesce(sum(post_like.score),0) as score, ( select score from post_like where post.id = post_like.post_id and post_like.fedi_user_id = MY_USER_ID ) as my_vote, from post left join post_like on post.id = post_like.post_id group by post.id;
BUT my ORM (rust diesel) doesn’t allow me to set or query for that necessary MY_USER_ID
field, since it’s a subquery.
I’d really love to be able to do something like:
select * from post_view where my_user_id = 'X';
Advertisement
Answer
Expose my_user_id on select clause of view
-- get all of the user's score on all post, regardless of the user liking the post or not create view post_view as select u.id as my_user_id, p.id as post_id, sum(pl.score) over (partition by p.id) as score, coalesce(pl.score, 0) as my_vote -- each u.id's vote from user u cross join post p left join post_like pl on u.id = pl.fedi_user_id and p.id = pl.post_id; select * from post_view where my_user_id = 'X';
UPDATE
This can obtain post’s scores even when no user is given
create view post_view as with all_post as ( select p.id as post_id, sum(pl.score) as score from post p left join post_like pl on p.id = pl.post_id group by p.id ) select u.id as my_user_id, ap.post_id, ap.score, coalesce(pl.score, 0) as my_vote from user u cross join all_post ap left join post_like pl on u.id = pl.fedi_user_id and ap.post_id = pl.post_id union all select '' as my_user_id, ap.post_id, ap.score, 0 as my_vote from all_post ap ; select * from post_view where my_user_id = 'X';
When no user is passed, select the query denoted by my_user_id of ''
select * from post_view where my_user_id = '';