Этот ответ такой же, как у Гордона Линоффа.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 уже предоставил.