I have a Postgres table that records which users are now in which chatroom.
It has two columns - "chatRoomId" and "userId".
So assuming I have records like this:
chatRoomX, A
chatRoomX, B
chatRoomY, B
chatRoomY, C
chatRoomY, D
(That means user A,B in chatRoomX. Users B,C,D in chatRoomY)
Now, given an array of ["A","B"], I need a SQL query that can determine which chatroom they are now in - the query should respond with "chatRoomX".
So far this is what I have got:
client.query('SELECT chatRoomId FROM tableName WHERE
userId = $1 INTERSECT SELECT chatRoomId FROM tableName WHERE
userId = $2', ["A","B"], function(err, results, done) { ... }
This query can successfully responds to me with "chatRoomX". But as you can see this query is hard coded and thus I need a better SQL that should work for an input array of users id with variable length.
Any ideas?
You could use PostgreSQL array logic to check if the array [A,B] is contained inside the array formed by all the people in a given chatroom.
Example:
SELECT ARRAY['A','B'] <@
ARRAY(SELECT userId FROM tableName WHERE chatRoomId='chatRoomX')
This will return a single boolean result (t or f), true if the two persons are in the chatroom and false otherwise.
<@ means "is contained by" for arrays. See Array Functions and Operators in postgres documentation.
EDIT: assuming the query should retrieve all the chatRoomId in which A and B are simultaneously present, this could be written as:
SELECT chatRoomId FROM
(SELECT chatRoomId, array_agg(userId) AS a
FROM tableName
GROUP BY userId) s
WHERE ARRAY['A','B'] <@ s.a;