Okay, so here are my tables: tests:
+----+------------+ | id | name | +----+------------+ | 1 | test-one | | 2 | test-two | | 3 | test-three | | 4 | test-four | | 5 | test-five | | 6 | test-six | +----+------------+
testGroups:
+----+-------------+ | id | name | +----+-------------+ | 1 | group-one | | 2 | group-two | | 3 | group-three | | 4 | group-four | | 5 | group-five | | 6 | group-six | | 7 | group-seven | | 8 | group-eight | | 9 | group-nine | | 10 | group-ten | +----+-------------+
and testGroupAssignments
+----+--------+---------+ | id | testID | groupID | +----+--------+---------+ | 1 | 1 | 1 | | 2 | 2 | 1 | | 3 | 2 | 2 | | 4 | 2 | 3 | | 5 | 3 | 1 | | 6 | 3 | 3 | | 7 | 4 | 1 | | 8 | 5 | 6 | | 9 | 5 | 7 | | 10 | 5 | 4 | +----+--------+---------+
What I want is to get every test
that has group-one
assigned to it, given it has no other group assigned to it.
+--------+-----------+ | testID | testName | +--------+-----------+ | 1 | test-one | | 4 | test-four | +--------+-----------+
I know that I should use a LEFT JOIN
and I tried to do:
SELECT t.id `testID`, t.name `testName` FROM tests `t` INNER JOIN testGroupAssignments `tga` ON t.id = tga.testID LEFT JOIN testGroupAssignments `tga2` ON t.id = tga.testID AND tga2.groupID != 1 INNER JOIN testGroups `tg` ON tg.id = tga.groupID WHERE tga.groupID = 1 AND tga2.groupID != 1 AND tga2.groupID IS NULL
Advertisement
Answer
You can try the following:
SELECT t.id AS testID, t.name AS testName FROM tests t INNER JOIN testGroupAssignments tga ON t.id = tga.testID INNER JOIN testGroups tg ON tg.id = tga.groupID WHERE tga.groupID = 1 AND NOT EXISTS ( SELECT 1 FROM testGroupAssignments WHERE testID = t.id AND groupID <> 1 )
In case you don’t want to show column values of the other tables you can use the following simple query:
SELECT * FROM tests t WHERE EXISTS ( SELECT 1 FROM testGroupAssignments tga WHERE tga.testID = t.id AND tga.groupID = 1 ) AND NOT EXISTS ( SELECT 1 FROM testGroupAssignments tga WHERE tga.testID = t.id AND tga.groupID <> 1 )