MySQL запрос на соединение, который должен вернуть отрицательный набор

Предположим, у меня есть 2 таблицы для пользователя и задачи. иметь user_id & статус в задаче со статусом, имеющим возможные значения "complete" и "not complete". Теперь я хочу получить пользователей, которые не выполнили даже 1 задачу. Самый грубый способ - это сначала найти пользователей, которые выполнили хотя бы 1 завершенную задачу и выполнить запрос "не в".

Любые лучшие способы достичь этого без "в" подзапроса. Обратите внимание, что набор данных огромен, и я не могу позволить себе долго блокировать таблицу задач!

3 ответа

Решение
SELECT *
FROM users u
WHERE NOT EXISTS (
    SELECT * FROM tasks t
    WHERE t.user_id = u.user_id
    AND t.status = 'complete'
    );

Когда task.user_id не может содержать NULL (т.е. имеет NOT NULL ограничение), LEFT JOIN с IS NULL ваш лучший выбор:

SELECT user.* FROM user
LEFT JOIN task ON (task.user_id = user.id AND task.status = 'complete')
WHERE task.user_id IS NULL

Попробуйте этот ниже запрос будет список пользователей, которые выполнили даже 1 задачу или более 1

SELECT u.*,
COUNT(  CASE WHEN  t.`status`= 'Completed' THEN t.`status` END  ) AS completed ,

COUNT(  CASE WHEN  t.`status`= 'Not completed' THEN t.`status` END  ) AS Not_completed

FROM `user`  u

LEFT JOIN `task` t  ON (u.id =t.user_id)

GROUP BY t.user_id HAVING completed >0

И это будет список пользователей, которые не выполнили даже 1 задачу

SELECT u.*,
COUNT(  CASE WHEN  t.`status`= 'Completed' THEN t.`status` END  ) AS completed ,

COUNT(  CASE WHEN  t.`status`= 'Not completed' THEN t.`status` END  ) AS Not_completed

FROM `user`  u

LEFT JOIN `task` t  ON (u.id =t.user_id)

GROUP BY t.user_id HAVING completed = 0

Смотрите скрипку для пользователей, выполняющих задачу

См. Скрипку для пользователей, которые не выполнили задачу

Другие вопросы по тегам