Postgres JSON加入,联盟

时间:2015-08-07 02:59:27

标签: json postgresql

我有帖子,滑动,通知。我想

  1. 按照分数对帖子进行排序
  2. 删除刷过的
  3. 通过帖子加入通知,并将加入的通知作为最高分
  4. 到目前为止,我已完成前两个但无法将通知添加为结果的第一个元素。这是前两个的工作查询。

    SELECT posts.id, posts.created_at, posts.data, ((posts.data)->>'score')::NUMERIC as score
    FROM  posts
    WHERE NOT EXISTS (
        SELECT  *
        FROM    swipes
        WHERE   ((swipes.data)->>'post_id')::INT = posts.id AND ((swipes.data)->>'user_id')::INT = 32)
    ORDER BY (data)->>'score' 
    LIMIT 5
    

    我尝试LEFT JOIN添加通知,但无法执行此操作。

    SELECT posts.id, posts.created_at, posts.data, ((posts.data)->>'score')::NUMERIC as score
    FROM  posts
    WHERE NOT EXISTS (
        SELECT  *
        FROM    swipes
        WHERE   ((swipes.data)->>'post_id')::INT = posts.id AND ((swipes.data)->>'user_id')::INT = 32)
    
    -- The part below is new
    UNION  ALL
    SELECT notifications.id, notifications.created_at, notifications.data, 9999999 AS score
    FROM   notifications
    
    --- THIS GIVES ERROR ---
    LEFT   JOIN posts USING (notifications.data)->>'post_id') 
    
    WHERE  ((notifications.data)->>'user_id')::INT = 32
    
    -- After join order by score
    ORDER BY score 
    LIMIT 5
    

    通知有一个名为data类型json的列。 notifications.data->post_id应由posts.id加入,分数为9999999.其中notifications.data->user_id应等于32。

1 个答案:

答案 0 :(得分:1)

如果您想要来自表格'通知'的行除了表格'帖子中的行之外,你应该UNION

SELECT id, created_at, data, (data->>'score')::numeric AS score
FROM posts
WHERE NOT EXISTS (
    SELECT 1
    FROM swipes
    WHERE ((swipes.data)->>'post_id')::int = posts.id
      AND ((swipes.data)->>'user_id')::int = 32)

UNION  ALL

SELECT id, created_at, data, 9999999 AS score
FROM notifications
LEFT   JOIN posts USING (notifications.data)->>'post_id')
WHERE (data->>'user_id')::int = 32

-- After join order by score
ORDER BY score 
LIMIT 5;

如果您想要添加表格列的通知'对于表格的帖子,你应该JOIN

SELECT p.id, p.created_at, p.data, (p.data->>'score')::numeric AS score
       n.id, n.created_at, n.data 
FROM posts p
JOIN notifications n ON n->>'post_id' = p->>'post_id' -- guessing here
WHERE NOT EXISTS (
    SELECT 1
    FROM swipes
    WHERE ((swipes.data)->>'post_id')::int = p.id
      AND ((swipes.data)->>'user_id')::int = 32)
WHERE (n.data->>'user_id')::int = 32
ORDER BY score 
LIMIT 5;