Reputation: 1188
I am working on a some kind of chat app. I store every message in a SQLite table such as following
| id | fromId | toId | date | content |
---------------------------------------------
| 0 | 1423 | 90 | ... | ... |
| 1 | 324 | 90 | ... | ... |
| 2 | 90 | 324 | ... | ... |
| 3 | 43 | 1423 | ... | ... |
| 4 | 439 | 324 | ... | ... |
| 5 | 90 | 324 | ... | ... |
| 6 | 324 | 43 | ... | ... |
I am trying to write a SQL request that shows chat dialog previews. In other words, I need to get the most recent message for each pair of two subscribers.
I guess that this is a frequent question, but I could not find any working solution (or I was not able to use them correctly).
Upvotes: 0
Views: 60
Reputation: 13248
Fiddle: http://sqlfiddle.com/#!7/3f4c2/2/0
select t.*
from tbl t
where id = (select max(x.id)
from tbl x
where (x.fromid = t.fromid and x.toid = t.toid)
or (x.fromid = t.toid and x.toid = t.fromid))
In the fiddle I created these indexes:
create index fromto on tbl (fromid, toid);
create index tofrom on tbl (toid, fromid);
To show you that this solution will utilize them:
Upvotes: 1
Reputation: 1270653
If you have indexes on chat(fromid, toid)
and chat(toid, fromid)
, then the most efficient way may be:
select c.*
from chat c
where not exists (select 1
from chat c2
where c2.fromId = c.fromId and c2.toId = c.toId and c2.id > c.id
) and
not exists (select 1
from chat c2
where c2.fromId = c.toId and c2.toId = c.fromId and c2.id > c.id
);
SQLite should be able to use the indexes for each of the subqueries.
Upvotes: 1
Reputation: 6979
Try this:
SELECT *
FROM chat c
WHERE NOT EXISTS
(SELECT * FROM chat
WHERE c.fromId IN (fromId, toId) AND c.toID IN (fromId, toID) AND c.id < id);
http://sqlfiddle.com/#!7/d57f3/2/0
Upvotes: 2