Reputation: 897
What is the correct way to perform this GET request? I currently have 4 tables:
events, event_comments, event_photos, event_users_going
The last 3 tables, event_comments, event_photos, and event_users_going all have a foreign key that uses events table's primary key.
What I am unsure about is, would I have to do a JOIN on all 4 tables or 4 individual queries? Because, each query on each table returns a different number of rows.
For example the first query would be on events:
SELECT * FROM events where e_id = 1
this returns 1 row.
The 2nd query:
SELECT * FROM event_photos where e_id = 1
this returns 12 rows
3rd Query:
SELECT * FROM event_comments WHERE e_id = 1
this returns 20 rows
4th Query:
SELECT * FROM event_users_going WHERE e_id = 1
this returns 30 rows
Upvotes: 0
Views: 63
Reputation: 1608
It depends on what is receiving the results. If it can process JSON and the overhead of doing so isn't a deal-breaker, you can do the following to include related rows as JSON arrays:
SELECT *,
COALESCE((
SELECT json_agg(event_photos)
FROM event_photos
WHERE event_photos.e_id = events.e_id
), '[]') AS photos,
COALESCE((
SELECT json_agg(event_comments)
FROM event_comments
WHERE event_comments.e_id = events.e_id
), '[]') AS comments,
COALESCE((
SELECT json_agg(event_users_going)
FROM event_users_going
WHERE event_users_going.e_id = events.e_id
), '[]') AS going
FROM events
WHERE e_id = 1;
Sample output:
e_id | photos | comments | going
------+--------------------------+-------------------------+-------
1 | [{"e_id":1,"url":"p1"}, +| [{"e_id":1,"txt":"c1"}] | []
| {"e_id":1,"url":"p2"}] | |
(1 row)
When returning JSON, you can take it a step further and build a result with a single column:
SELECT json_build_object(
'event', events,
'photos', COALESCE((
SELECT json_agg(event_photos)
FROM event_photos
WHERE event_photos.e_id = events.e_id
), '[]'),
'comments', COALESCE((
SELECT json_agg(event_comments)
FROM event_comments
WHERE event_comments.e_id = events.e_id
), '[]'),
'going', COALESCE((
SELECT json_agg(event_users_going)
FROM event_users_going
WHERE event_users_going.e_id = events.e_id
), '[]')
)
FROM events
WHERE e_id = 1;
Sample output:
json_build_object
------------------------------------------------------------------------------
{"event" : {"e_id":1}, "photos" : [{"e_id":1,"url":"p1"}, +
{"e_id":1,"url":"p2"}], "comments" : [{"e_id":1,"txt":"c1"}], "going" : []}
(1 row)
Upvotes: 2
Reputation: 3970
Joins are costly and can lead to redundant data as well leaving the total count of rows much greater than actual sum of rows obtained by your above 4 queries.
Therefore, you must use these 4 seperate queries as they also contain different data as youve already mentioned above
Upvotes: 2