UNIQUE userid
Each user can only have at most one entry (like the question seems to ask).
SELECT (SELECT groupid FROM tbl WHERE userid = 5)
= (SELECT groupid FROM tbl WHERE userid = 6);
Assuming userid
is UNIQUE
.
Returns TRUE
or FALSE
exactly like requested.
- or NULL
if a userid
is not found or groupid
is NULL.
UNIQUE (userid, groupid)
Each user can only have multiple entries (as clarified in the comment):
Share all groups?
SELECT EXISTS (
SELECT 1
FROM (SELECT groupid FROM tbl2 WHERE userid = 5) a
FULL JOIN (SELECT groupid FROM tbl2 WHERE userid = 6) b USING (groupid)
WHERE a.groupid IS NULL OR
b.groupid IS NULL
) AS share_all;
Share at least one group?
SELECT EXISTS (
SELECT groupid FROM tbl2 WHERE userid = 8
INTERSECT
SELECT groupid FROM tbl2 WHERE userid = 9
) AS share_min_one;
Or
SELECT EXISTS (
SELECT 1
FROM (SELECT groupid FROM tbl2 WHERE userid = 5) a
JOIN (SELECT groupid FROM tbl2 WHERE userid = 6) b USING (groupid)
) AS share_min_one;
Share exactly one group?
SELECT count(*) = 1 AS share_exactly_one
FROM (SELECT groupid FROM tbl2 WHERE userid = 5) a
JOIN (SELECT groupid FROM tbl2 WHERE userid = 6) b USING (groupid);
SQL Fiddle with better test data.
All of these queries are fast with an index on userid
. Faster with a multicolumn index on (userid, groupid)
in Postgres 9.2+.
Ultimately this is a case of relational-division. Here's an arsenal of query techniques: