Выберите, где столбец является нулевым или нет в подзапросе - PullRequest
2 голосов
/ 07 марта 2012

У меня есть 2 таблицы с именами и графиком дат, связанных с этими именами.Я пытаюсь получить список всех имен, которые никогда не были запланированы или не были запланированы в течение последних 2 месяцев.

   SELECT n.name, MAX(s.date) 
     FROM names n
LEFT JOIN schedule s ON n.id = s.nameid
    WHERE s.nameid IS NULL 
       OR s.nameid NOT IN (SELECT nameid 
                             FROM schedule 
                            WHERE date > NOW() - INTERVAL 2 MONTH)
 GROUP BY n.id

Когда я запускаю этот запрос, MySQL берет на себя процессор и не отвечает.

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

   SELECT n.name, MAX(s.date) 
     FROM names n
LEFT JOIN schedule s ON n.id = s.nameid
    WHERE s.nameid IS NULL
 GROUP BY n.id

   SELECT n.name, MAX(s.date) 
     FROM names n
LEFT JOIN schedule s ON n.id = s.nameid
    WHERE s.nameid NOT IN (SELECT nameid 
                             FROM schedule 
                            WHERE date > NOW() - INTERVAL 2 MONTH)
 GROUP BY n.id

Я не уверен, как заставить этот запрос работать для возвратавсе результаты или почему он занимает центральный процессор.

Ответы [ 2 ]

1 голос
/ 07 марта 2012

OR печально известен плохим исполнителем в каждой базе данных, о которой я могу думать.A UNION, если часто лучшая альтернатива:

   SELECT n.name, MAX(s.date) 
     FROM names n
LEFT JOIN schedule s ON n.id = s.nameid
    WHERE s.nameid IS NULL
 GROUP BY n.id
UNION
   SELECT n.name, MAX(s.date) 
     FROM names n
LEFT JOIN schedule s ON n.id = s.nameid
    WHERE s.nameid NOT IN (SELECT nameid 
                             FROM schedule 
                            WHERE date > NOW() - INTERVAL 2 MONTH)
 GROUP BY n.id

UNION удалит дубликаты - если нет проблем с дубликатами, используйте UNION ALL (это быстрее, потому что не удаляет дубликаты).

Кроме того, последний запрос имеет критерии к таблице OUTER JOIN'd в предложении WHERE - этот критерий применяется после JOIN.Вы можете получить разные результаты, используя:

   SELECT n.name, MAX(s.date) 
     FROM names n
LEFT JOIN schedule s ON s.nameid = n.id
                    AND s.nameid NOT IN (SELECT nameid 
                                           FROM schedule 
                                          WHERE date > NOW() - INTERVAL 2 MONTH)
 GROUP BY n.id

В приведенном выше примере критерии будут применяться до ВНЕШНЕГО СОЕДИНЕНИЯ.Для ВНУТРЕННИХ СОЕДИНЕНИЙ это можно игнорировать - критерии в любом месте эквивалентны.

0 голосов
/ 07 марта 2012

Не зная вашей полной схемы, что-то не так с

   SELECT n.name, max(s.date)
     FROM names n
LEFT JOIN schedule s 
       ON n.id = s.nameid
    WHERE s.nameid IS NULL
       OR s.date <= DATE_SUB(CURDATE(), INTERVAL 2 MONTH)
 GROUP BY n.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...