I am kind of new to the more advanced topics of PLSQL, so hopefully someone can help me out.
The problem: I have a table with messages sent between an admin and users. The table has a message_parent with FK to the same table message_id field: in case the field is populated, then it means that message was sent as a reply to a previous message. I need to select all the messages that are part of the same conversation and display them. Can this be done with a single query or do I need a procedure to handle that kind of logic? As I understand, it needs to be recursive, since the message_id by which I am searching, is always changing
Example Messages table:
|message_id|parent_id|message_content|
|----------|---------|---------------|
|101 |100 | foo |
|100 |97 | bar |
|99 |(null) | Left out |
|97 |(null) | baz |
So the correct query selecting message_content should return "baz", "bar" and "foo" but not "Left out" (since baz is the original message). This would be simple if there were e.g. only two messages that can be tied together or e.g. a thread_id column, that would link all messages in the same 'thread', but with the parent_id's constantly shifting, I am having trouble figuring it out.
In Oracle this is easily done using
CONNECT BY
This walks the tree from top to bottom.
If you want to walk the tree from a single message to the root, change the
start with
and theconnect by
part:To get the entire message context based off of a single
message_id
, you can use two hierarchical queries. One walks the message tree from the current messagedown
to the root, while the second walks backup
from the root to the leaves. Assuming the current message_id is 100 (though values of 101 or 97 would have the same end result), the following query returns all related messages (all except 'Left out'):In the
down
query I've limited it to return only the root message node (connect_by_isleaf
) such thatstart_id
will be the root message, and included the current message_id ascurr_id
for reference in theup
query where I've included a column to mark the current message with an asterisk.