I have this table messages
;
sender_id recipient_id
1 2
1 3
1 3
2 1
3 1
2 3
I wish to select rows such that:
sender_id
or receiver_id
= current_user.id
.I.e. I want to select unique from table where sender_id = 2
or recipient_id = 2
and I need this result:
sender_id recipient_id
2 1
2 3
How to do it?
Why? Because I wish to build a facebook-like inbox in which sent and received messages are aggregated, and this query is the bottleneck so far.
I am using rails 3.2 and Postgres 9.3.
SELECT sender_id AS user_id, recipient_id AS other_user_id
FROM messages
WHERE sender_id = $current_user_id
UNION
SELECT recipient_id, sender_id
FROM messages
WHERE recipient_id = $current_user_id
-- ORDER BY 1, 2 -- optional
UNION
(not UNION ALL
) removes duplicates from the result makingDISTINCT
unnecessary.
You might want to add ORDER BY
at the end for sorted output.
Assuming a big table with relatively few qualifying rows, two btree indexes typically deliver best performance. One with leading or only sender_id
, another one with leading or only recipient_id
.
A single multicolumn index on (sender_id, receiver_id)
or vice versa also works, but typically slower. See:
With ANSI SQL:
SELECT DISTINCT sender_id, reciepient_id
FROM messages
WHERE (sender_id = current_user.id or reciepient_id = current_user.id)
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