0

Rows as follow:

|id.   |sender|receiver| type| content   | time |
|------|------|--------|-----|-----------|------|
|uuid01|     x|       y| text|      hello|time01|
|uuid02|     y|       z| text|how are you|time02|
|uuid03|     y|       x| text|       haha|time03|
|uuid04|     x|       y|image|           |time04|

How can i merge x->y / y->x to be one conversation? As follows:

|id |type | content   | time |
|---|-----|-----------|------|
|x-y|image|           |time04|
|y-z|text |how are you|time02|
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
jim ying
  • 361
  • 4
  • 17

2 Answers2

1

Assuming all involved columns NOT NULL.

SELECT DISINCT ON (LEAST(sender, receiver), GREATEST(sender, receiver))
       LEAST(sender, receiver) || '-' || GREATEST(sender, receiver) AS id
     , type, content, time
FROM   tbl
ORDER  BY LEAST(sender, receiver), GREATEST(sender, receiver), time DESC;

See:

Performance optimization is possible, depending on undisclosed details of your relational design and data distribution.

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
0

This way you could group by exchanging the values of more than two columns:

Defining function array_sort:

CREATE OR REPLACE FUNCTION array_sort(ANYARRAY)
RETURNS ANYARRAY LANGUAGE SQL
AS $$
SELECT ARRAY(SELECT unnest($1) ORDER BY 1);
$$;

Sql query:

SELECT DISTINCT ON (array_sort(string_to_array(sender, ',') || string_to_array(receiver, ',')))
   sender || '-' || receiver AS idSR,
   type,
   content,
   time
FROM messages
ORDER BY array_sort(string_to_array(sender, ',') || string_to_array(receiver, ',')), id DESC;
nachospiu
  • 2,009
  • 2
  • 8
  • 12