Odkryłem, że piszę:
select 'yes'
where exists(select * from foo where val=1)
and not exists(select * from foo where val<>1);
i zastanawiam się, czy istnieje bardziej zwięzły sposób bez poświęcania zbyt dużej czytelności.
Znalazłem jeden sposób, który publikuję jako odpowiedź, ale nie jestem do końca z niego zadowolony i byłbym bardzo zainteresowany alternatywami
W tym przypadku val
jest unikalny w obrębie foo
- nie ma duplikatów
postgresql
duplication
Jack mówi, że spróbuj topanswers.xyz
źródło
źródło
count(distinct val)
, choć w moim przypadku w rzeczywistości nie ma to różnicyOdpowiedzi:
Zwięzły, szybki (szczególnie z wieloma wierszami), mój ulubiony pod względem czytelności i działałby również z duplikatami:
Zwraca
TRUE
/FALSE
.. lubNULL
- tylko w przypadku dokładnie jednego wiersza zval IS NULL
, ponieważcount()
nigdy nie zwracaNULL
lub nie ma wiersza.Drugi
1
w przykładzie po prostu jest taki sam jak pierwszy, z powodu twojego przykładu.Zapytanie w pytaniu kończy się niepowodzeniem z
NULL
wartościami. Rozważ proste demo:IS DISTINCT FROM
naprawiłoby to, ale nadal może się nie powieść z duplikatami wval
- co wykluczyłeś w tym przypadku.Twoja odpowiedź działa dobrze.
Zwraca
'yes'
/ brak wiersza.Wolałbym jednak tę krótszą formę. Nie zapominaj, że PostgreSQL (w przeciwieństwie do Oracle) ma odpowiedni
boolean
typ .Zwraca
TRUE
/FALSE
/NULL
.źródło
Odmiana odpowiedzi @ Erwina. Nie
COUNT()
w ogóle, tylkoMIN()
iMAX()
. Może być nieco bardziej wydajny z dużym stołem i (nie w twoim przypadku) duplikatemval
:źródło
źródło
Ten jeden powraca
true
,false
lub pusty wynik:źródło
false
jeśli istnieją wartościfoo
gdzieval<>1
?NULL
wartości, która nie została wykluczona w tym przypadku.NULL
można opracować za pomocą,IS [NOT] DISTINCT FROM
jak sądzę.LEFT JOIN foo j ON j.val <> foo.val
na początku nie wykrywa wierszaj.val IS NULL
z. Jeśli dołączysz toON j.val IS DISTINCT FROM foo.val
, musisz sprawdzić kolejną kolumnęj
zdefiniowaną,NOT NULL
aby odróżnić te dwa przypadki. Ale nie zdefiniowano żadnej dodatkowej kolumny.