Im trying to get my head around the most effective way to achieve intended result.
After some reading i realize turning only_full_group_by=off
is a bad idea.
I have the following data:
Table test
id task user 1 21 4 2 22 4 3 23 3 4 25 3 5 25 4 6 22 4
Goal
i want to return all task values that do not have an other user assigned to it. So user=4
should return [21,22]
and user=3
=> [23]
Tried solutions
to achieve this using only_full_group_by=off
i put together the following SQL
SELECT task, count(distinct user), user FROM test
GROUP BY task
HAVING count(distinct user) = 1 AND user=4
But to achieve a similar result with only_full_group_by=on
the query seems unnecessarily complex (maybe it isnt, let me know)
SELECT DISTINCT test.task, test.user FROM test, (
SELECT task, count(distinct user) from test
GROUP BY task
HAVING count(distinct user) = 1
) as tmp WHERE user = 4 AND test.task=tmp.task
Both queries returns "same" output but the latter seems unnecessarily complex and possibly inefficient. But im no SQL expert.
Is there a more efficient way to achive this outcome?
2
Answers
You could do this with a
LEFT JOIN
that looks for another user on the same task, then enforce the constraint that this should not match any rows:This query is essentially the same as Rob Eyre’s answer but written using NOT EXISTS, instead of the traditional anti-join:
Unless there is a reason for having the surrogate PK, I would remove it and make
(task user)
the PK and add a secondary on(user, task)
, after removing the duplicates.Here’s a db<>fiddle.