I have a PostgreSQL table holding chats between two people.
Table columns:
id (PRIMARY KEY)
professional_id (FOREIGN KEY)
request_id (FOREIGN KEY)
message
created_by (FOREIGN KEY)
created_at
read_at
I need to have the list of chats and for each chat I need to have the number of unread messages (i.e. WHERE read_at IS NULL
).
This is my query to get the chat list for that request:
SELECT
rm.professional_id,
CONCAT(u.first_name, ' ', u.last_name) AS professional_full_name,
FROM request_messages AS rm
LEFT JOIN users AS u ON (rm.professional_id = u.id)
WHERE rm.request_id = $1
GROUP BY rm.professional_id, professional_full_name
I need a third output column to display a count WHERE read_at IS NULL
.
Use the aggregate FILTER
clause. See:
SELECT rm.professional_id
, concat_ws(' ', u.first_name, u.last_name) AS professional_full_name
, rm.unread_count
FROM (
SELECT professional_id
, count(*) FILTER (WHERE read_at IS NULL) AS unread_count
FROM request_messages
WHERE request_id = $1
GROUP BY professional_id
) rm
LEFT JOIN users u ON rm.professional_id = u.id
-- ORDER BY rm.unread_count DESC, professional_full_name -- ?
;
Also, it's typically best to aggregate first, and join later:
About concat_ws()
: