Reputation: 4007
I have posts, swipes, notifications. I want to
So far I have done the first two but couldn't add the notifications as the first elements to the result. This is the working query of the first two.
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
I tried LEFT JOIN
for adding notifications but couldn't do it.
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
notifications has a column named data
type json
. notifications.data->post_id
should joined by posts.id
with it by score 9999999. where notifications.data->user_id
should be equal to 32.
Upvotes: 2
Views: 556
Reputation: 32189
If you want the rows from table 'notifications' in addition to the rows from table 'posts', then you should 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;
If instead you want to add the columns of table 'notifications' to those of table 'posts, then you should 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;
Upvotes: 1