2015-09-03 3 views
0

У меня есть следующий запрос -как написать предикат, как NOT IN предиката

select ssn, fname, lname 
from employee, department 
where (dname, dno) in (select dname, dno 
         from department, employee 
         where dno=dnumber 
         and dname <> 'Headquarters' 
         and dname <> 'Administration'); 

`

Он возвращает ssn, fname и lname сотрудников, которые не работают в штаб-квартире или административный отдел.

У меня возникли проблемы с изменением логики и выяснением того, как получить тот же результат, используя «не в». Из того, что я собрал, предикат «in» проходит через таблицы и проверяет, может ли он создавать кортежи fname, lname и ssn, который основан на номере отдела из таблицы сотрудников, соответствующей номеру отдела в таблице отдела.

+0

Я не понимаю ... Почему бы вам просто не использовать «не в»? Каков ожидаемый результат? Вы также можете сделать соединение и получить гораздо более простой запрос ... –

+0

затем сделать его 'не в', ** ИЛИ ** изменить на' dname = '? –

+1

и нет смысла использовать подзапрос для этого, тем более, что подзапрос находится в одних и тех же таблицах. почему вы не можете просто «выбрать» у сотрудника, где dname not in ('hq', 'admin') '? –

ответ

1

Вы должны инвертировать тест в WHERE пункте подзапроса, используя de Morgan's Law

select ssn, fname, lname 
from employee, department 
where (dname, dno) not in (
    select dname, dno 
    from department, employee 
    where dno != dnumber or dname IN ('Headquarters', 'Administration')); 
+0

Ах, конечно, спасибо. По какой-то причине Oracle не любит использование IN внутри вложенного select. Однако он работает следующим образом: где dno <> dnumber или dname = 'Headqaurters' или dname = 'Administration'); Знаете ли вы, почему это так? – User9193

+0

Мой ответ для MySQL, я не знаю Oracle. Вероятно, вы должны сказать что-то в этом вопросе, чтобы подчеркнуть, что вам нужны решения для обоих - я не заметил, что у вас есть оба тега. – Barmar

+0

Вышеприведенный запрос содержит слишком много открытых скобок '' '' '' '' '' '' '' sub select '' или 'too few close close close') 'так что если вы скопировали его дословно, что могло бы стать источником отказа оператора in. Добавьте еще один заключительный паз в конце, и он вполне может работать. – Sentinel

0

Я считаю, что сглаживание помогает мне следить за вещи:

SELECT emp.ssn, emp.fname, emp.lname 
FROM employee emp, department dep1 
WHERE emp.dnumber = dep1.dno /* link the tables here */ 
AND (dep1.dno NOT IN (  /* subquery filters eligible results */ 
    SELECT dep2.dno 
    FROM department dep2 
    WHERE dep2.dname <> 'Headquarters' 
    AND dep2.dname <> 'Administration') 
); 

Примечания: Я не проверял это , но он должен быть близок.

Смежные вопросы