Как инвертировать или отфильтровать двух сотрудников, которые работают над проектами в других отделах? - PullRequest
1 голос
/ 15 апреля 2019

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

Я соединил три таблицы вместе и попытался использовать оператор NOT IN, но мне кажется, что я не могу использовать его правильно?

Вот мой код

SELECT e.FNAME,
       e.LNAME
FROM ballen15db.EMPLOYEE e,
     ballen15db.WORKS_ON w
WHERE e.SSN=w.ESSN
  AND EXISTS
    (SELECT *
     FROM ballen15db.PROJECT p
     WHERE w.PNO=p.PNUMBER
       AND p.DNUM!=e.DNO )
GROUP BY e.SSN;

Ожидаемые результаты

John Smith
Joyce English
Ramesh Rayan
Alicia Zelaya
Ahmad Jabbar
James Borg

Фактические результаты

Franklin Wong
Jennifer Wallace

enter image description here

Ответы [ 2 ]

2 голосов
/ 15 апреля 2019

Во-первых, научитесь использовать правильный синтаксис JOIN. Затем используйте GROUP BY и HAVING для вашей логики:

select e.SSN, e.FNAME, e.LNAME 
from ballen15db.EMPLOYEE e join
     ballen15db.WORKS_ON w
     on e.SSN = w.ESSN join
     ballen15db.PROJECT p 
     on w.PNO = p.PNUMBER 
group by e.SSN, e.FNAME, e.LNAME 
having sum(p.dum <> e.dno) = 0;

having подсчитывает, сколько раз отличаются номера отделов. = 0 говорит, что таких строк не существует.

1 голос
/ 15 апреля 2019

Этот ответ такой же, как у Гордона Линоффа.every включено в стандарт SQL.У Postgres это есть, у MySQL нет.Если MySQL имеет every, Гордон записал бы его как:

select
    e.SSN,
    e.FNAME,
    e.LNAME
from
    ballen15db.EMPLOYEE e
    join ballen15db.WORKS_ON w on e.SSN = w.ESSN
    join ballen15db.PROJECT p on w.PNO = p.PNUMBER
group by
    e.SSN,
    e.FNAME,
    e.LNAME
having
    every(p.dum = e.dno);

every недоступно в MySQL.Поэтому я написал бы выше, используя вместо MySQL bit_and, чтобы сохранить логику.Не нужно использовать комбинацию инвертирования логики, суммы и 0.

select
    e.SSN,
    e.FNAME,
    e.LNAME
from
    ballen15db.EMPLOYEE e
    join ballen15db.WORKS_ON w on e.SSN = w.ESSN
    join ballen15db.PROJECT p on w.PNO = p.PNUMBER
group by
    e.SSN,
    e.FNAME,
    e.LNAME
having
    bit_and(p.dum = e.dno);

Если ваша СУБД не имеет every, bool_and или bit_and, и вы хотите избежать инверсиилогики (суммирование), вы можете использовать min вместо sum:

select
    e.SSN,
    e.FNAME,
    e.LNAME
from
    ballen15db.EMPLOYEE e
    join ballen15db.WORKS_ON w on e.SSN = w.ESSN
    join ballen15db.PROJECT p on w.PNO = p.PNUMBER
group by
    e.SSN,
    e.FNAME,
    e.LNAME
having
    min(p.dum = e.dno) = 1

Логика работает так: если отдел из проектов сотрудника отличается от отдела сотрудника, это приведет к ложному/ 0, тогда min вернет 0. Если отдел из проектов сотрудника совпадает с отделом сотрудника, это приведет к значению true / 1, тогда, если все отделы из проектов сотрудника совпадают с отделом сотрудника, то min будетreturn 1.

Конечно, если использовать MySQL, лучше использовать bit_and, он имеет больше семантики, чем min и 1 комбо, из-за части _and, и имеет гораздо больше семантики, чемкомбинация перевернутой логики, sum и 0. bit_and немного читабелен, каламбур:)

Но, по сути, ноль или единица указывают на логические значения, используемые для проверки, является ли что-то истинным или нет в SQL?- Б. Аллен

Да, но это в основном из-за отсутствия надлежащей логической поддержки этих баз данных SQL.Большинство баз данных SQL, в которых отсутствует надлежащая логическая поддержка, вместо этого используют ноль или единицу.Postgres имеет надлежащую логическую поддержку.

В MySQL его логическое значение по сути просто integer .tinyint(1) чтобы быть точным.Вы можете думать, что tinyint(1) в MySQL ведет двойную жизнь, это и целое число, и логическое значение.

Хотя MySQL (как и SQL Server) не имеет действительного логического значения, по крайней мере MySQL работает лучше, чем SQL Server, поскольку MySQL позволяет своим tinyint действовать как логическое значение.

Так что, кромевозможность сделать это в MySQL:

select * from hero where hero.can_fly = 1

Вы также можете сделать следующее в MySQL, поэтому ваш запрос теперь выглядит как естественный английский, что и должен обеспечивать язык с хорошей булевой поддержкой:

select * from hero where hero.can_fly

В то время как в SQL Server вы не можете сделать where hero.can_fly, вы должны сделать where hero.can_fly = 1.

Логическое значение Postgres будет разрешать только следующее.Postgres рекомендует пользователям использовать правильное логическое выражение.Это также похоже на выражение мыслей на естественном языке.

where hero.can_fly

where not hero.can_fly

Postgres не разрешает запускать этот код:

where hero.can_fly = 1

where hero.can_fly = 0

На первый взгляд кажется, что MySQL предлагает большую гибкость,Кто-то скажет, что это не ошибка, это особенность.Тем не менее, MySQL не будет отмечать следующее как неправильные коды, скажем, пользователь неправильно набрал значение.MySQL с радостью выполнит код, несмотря на то, что логическое выражение имеет недопустимое значение.

where hero.can_fly = 2

where hero.can_fly = -1

Так что это ошибка.

Я также предполагаю, что min будет минимальным значением, возвращаемым обратно, если условиеэто правда или ложь?- Б. Аллен

Верно.В MySQL истинное выражение отображается на 1, ложное - на ноль.Таким образом, если есть хотя бы одно выражение из строк, которое дает ложный результат, min вернет 0. Если все строки дают истинный результат, min вернет 1.

Тесты: https://www.db -fiddle.com / ж / spibD9EhCVKHbnyu5GjCV8 / 4

Хорошее чтение:

https://blog.jooq.org/2014/12/18/a-true-sql-gem-you-didnt-know-yet-the-every-aggregate-function/

http://www.anicehumble.com/2019/04/not-every-rdbms-has-every.html

С Twitter :

'Языки программирования учат васне хотеть того, чего не дают.- Пол Грэм

Однако для Postgres он учит своих пользователей хотеть, чтобы другие СУБД предоставляли то, что Postgres уже предоставил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...