This is one simple solution.
Schema (PostgreSQL v15)
CREATE TABLE "Activity"
(
"id" INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY,
"designation" TEXT NOT NULL
);
CREATE TABLE "UserType"
(
"id" INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY,
"designation" TEXT NOT NULL
);
CREATE TABLE "User"
(
"id" INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY,
"name" TEXT NOT NULL,
"typeId" INTEGER NOT NULL REFERENCES "UserType"("id")
-- ... and other fields
);
CREATE TABLE "Activity_UserType"
(
"id" INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY,
"activityId" INTEGER NOT NULL REFERENCES "Activity"("id"),
"userTypeId" INTEGER NOT NULL REFERENCES "UserType"("id")
);
INSERT INTO "UserType"(designation) VALUES ('UserType 1');
INSERT INTO "UserType"(designation) VALUES ('UserType 2');
INSERT INTO "UserType"(designation) VALUES ('UserType 3');
INSERT INTO "Activity"(designation) VALUES ('Activity All User Types');
INSERT INTO "Activity"(designation) VALUES ('Activity UserType 1');
INSERT INTO "Activity"(designation) VALUES ('Activity UserType 2');
INSERT INTO "Activity"(designation) VALUES ('Activity UserType 2 and 3');
INSERT INTO "Activity_UserType"("activityId", "userTypeId") VALUES (2, 1);
INSERT INTO "Activity_UserType"("activityId", "userTypeId") VALUES (3, 2);
INSERT INTO "Activity_UserType"("activityId", "userTypeId") VALUES (4, 2);
INSERT INTO "Activity_UserType"("activityId", "userTypeId") VALUES (4, 3);
INSERT INTO "User"(name, "typeId") VALUES ('User - Type 1', 1);
INSERT INTO "User"(name, "typeId") VALUES ('User - Type 2', 2);
INSERT INTO "User"(name, "typeId") VALUES ('User - Type 3', 3);
Query #1 -- Should return all users ('User - Type 1' and 'User - Type 2' and 'User - Type 3')
SELECT "User"."id"
, "User"."name"
, "User"."typeId"
FROM "User"
JOIN "UserType"
ON "User"."typeId" = "UserType"."id"
WHERE NOT EXISTS
(
SELECT 1
FROM "Activity_UserType"
WHERE "Activity_UserType"."activityId" = 1
)
OR EXISTS
(
SELECT 1
FROM "Activity_UserType"
WHERE "UserType"."id" = "Activity_UserType"."userTypeId"
AND "Activity_UserType"."activityId" = 1
);
id |
name |
typeId |
1 |
User - Type 1 |
1 |
2 |
User - Type 2 |
2 |
3 |
User - Type 3 |
3 |
Query #2 -- Should return users Type1 ('User - Type 1')
SELECT "User"."id"
, "User"."name"
, "User"."typeId"
FROM "User"
JOIN "UserType"
ON "User"."typeId" = "UserType"."id"
WHERE NOT EXISTS
(
SELECT 1
FROM "Activity_UserType"
WHERE "Activity_UserType"."activityId" = 2
)
OR EXISTS
(
SELECT 1
FROM "Activity_UserType"
WHERE "UserType"."id" = "Activity_UserType"."userTypeId"
AND "Activity_UserType"."activityId" = 2
);
id |
name |
typeId |
1 |
User - Type 1 |
1 |
Query #3 -- Should return users Type2 ('User - Type 2')
SELECT "User"."id"
, "User"."name"
, "User"."typeId"
FROM "User"
JOIN "UserType"
ON "User"."typeId" = "UserType"."id"
WHERE NOT EXISTS
(
SELECT 1
FROM "Activity_UserType"
WHERE "Activity_UserType"."activityId" = 3
)
OR EXISTS
(
SELECT 1
FROM "Activity_UserType"
WHERE "UserType"."id" = "Activity_UserType"."userTypeId"
AND "Activity_UserType"."activityId" = 3
);
id |
name |
typeId |
2 |
User - Type 2 |
2 |
Query #4 -- Should return users Type2 and Type3 ('User - Type 2' and 'User - Type 3')
SELECT "User"."id"
, "User"."name"
, "User"."typeId"
FROM "User"
JOIN "UserType"
ON "User"."typeId" = "UserType"."id"
WHERE NOT EXISTS
(
SELECT 1
FROM "Activity_UserType"
WHERE "Activity_UserType"."activityId" = 4
)
OR EXISTS
(
SELECT 1
FROM "Activity_UserType"
WHERE "UserType"."id" = "Activity_UserType"."userTypeId"
AND "Activity_UserType"."activityId" = 4
);
id |
name |
typeId |
2 |
User - Type 2 |
2 |
3 |
User - Type 3 |
3 |
View on DB Fiddle