如何将变量传递给视图中的子选择

时间:2019-04-01 06:39:07

标签: sql postgresql

我有一个帖子列表,post_like,并且我需要一个查询,该查询将为我提供这些帖子的喜欢总数,并为这些帖子提供给定的特定用户的喜欢。这意味着我需要一种很好的方式来提供MY_USER_ID作为输入数据。

这是一个有效的查询

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;

但是我的ORM(生锈的柴油)不允许我设置或查询该必要的MY_USER_ID字段,因为它是子查询。

我真的很想能够做类似的事情:

select * 
from post_view 
where my_user_id = 'X';

3 个答案:

答案 0 :(得分:1)

您可以在on子句

中移动该条件
create view post_view as 
select post.id,
coalesce(sum(post_like.score),0) as score
from post
left join post_like
on post.id = post_like.post_id and  post_like.fedi_user_id = MY_USER_ID
group by post.id;

答案 1 :(得分:1)

在视图的选择子句上暴露my_user_id

-- 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';

更新

即使没有用户,也可以获得帖子的分数

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';

当没有用户通过时,选择''的my_user_id表示的查询

select * from post_view where my_user_id = '';

答案 2 :(得分:1)

您可以使用条件聚合将逻辑移至select

select p.id,
       coalesce(sum(pl.score), 0) as score,
       sum( (pl.fedi_user_id = MY_USER_ID)::int ) as my_vote
from post p left join
     post_like pl
     on p.id = pl.post_id
group by p.id;