I'm trying to track the source of comments on a blog site and my question relates to priority JOINing on multiple columns with an OR
statement.
The comments table:
Column | Type
--------------------+-------------------------
id | integer
text | character varying(1024)
session_source_id | integer
user_source_id | integer
If I have a query like so:
SELECT s.type, COUNT(c.id) FROM comments c
LEFT JOIN sources s ON (c.session_source_id = s.id OR c.user_source_id = s.id)
GROUP BY 1;
There are situations where we know the user source but NOT the session source (which is why I used OR
), but I want to prioritize the session_source_id if we also have a user_source_id and those two ids differ.
(there are also situations where we don't know either sources and both columns are null, hence the LEFT JOIN
)
Does that query prioritize the JOIN on session_source_id since it's listed first in the joining OR
statement? How does Postgres handle OR conditionals in JOIN statements?
No, it doesn't matter.
The order of the conditions in the ON clause doesn't matter. The queries per query pair you are showing are equal. If one query in a pair gives you different rows than the other, then this cannot be caused by the queries you are showing.
If you'd like to get data stored in tables joined by a compound key that's a primary key in one table and a foreign key in another table, simply use a join condition on multiple columns. In one joined table (in our example, enrollment ), we have a primary key built from two columns ( student_id and course_code ).
If you want compare two or more columns. you must write a compound WHERE clause using logical operators Multiple-column subqueries enable you to combine duplicate WHERE conditions into a single WHERE clause.
Posting GarethD's comment as answer and Wiki, so that it won't be lost:
Try COALESCE instead of OR...
LEFT JOIN sources s
ON s.id = COALESCE(c.session_source_id, c.user_source_id)
Using OR
won't prioritize the conditions, if both conditions are true, both records will be returned.
If you want any priority, you can use CASE EXPRESSION
which will break the moment a condition is met :
SELECT s.type, COUNT(c.id) FROM comments c
LEFT JOIN sources s
ON (CASE WHEN c.session_source_id = s.id THEN 1
WHEN c.user_source_id = s.id THEN 1
ELSE 0
END = 1)
GROUP BY 1;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With