Czy postgres jest sposobem na połączenie IS DISTINCT FROM
z ANY
innym sposobem na uzyskanie tego samego rezultatu?
select count(*)
from (select 'A' foo union all select 'Z' union all select null) z
where foo <> any(array[null, 'A']);
count
-------
1
(1 row)
select count(*)
from (select 'A' foo union all select 'Z' union all select null) z
where foo is distinct from any(array[null, 'A']);
ERROR: syntax error at or near "any"
LINE 3: where foo is distinct from any(array[null, 'A']);
^
postgresql
null
postgresql-9.3
Jack mówi, że spróbuj topanswers.xyz
źródło
źródło
IS DISTINCT FROM
być operatorem? Wydaje się, że jest to jedynie techniczne ograniczenie parsera, a nie kwestia semantyczna.Operator
Opiera się to na sprytnym operatorze @ Daniela .
Będąc przy tym, utwórz kombinację funkcji / operatora, używając typów polimorficznych . Następnie działa dla każdego typu - podobnie jak konstrukcja.
I wykonaj tę funkcję
IMMUTABLE
.Szybkie wyszukiwanie z symbolhoundem było puste, więc operator
<!>
nie wydaje się być używany w żadnym module.Jeśli zamierzasz często korzystać z tego operatora, możesz go trochę dopracować, aby pomóc planerowi zapytań ( jak sugerowany w komentarzu Losthorse ). Na początek możesz dodać klauzule
COMMUTATOR
iNEGATOR
, aby wspomóc optymalizator zapytań. ZamieńCREATE OPERATOR
z góry na:I dodaj:
Ale dodatkowe klauzule nie pomogą w danym przypadku użycia, a zwykłe indeksy nadal nie będą używane. Osiągnięcie tego jest znacznie bardziej wyrafinowane. (Nie próbowałem.) Aby uzyskać szczegółowe informacje, przeczytaj rozdział „Informacje dotyczące optymalizacji operatora” w podręczniku.
Przypadek testowy
Przypadek testowy w pytaniu może się powieść tylko wtedy, gdy wszystkie wartości w tablicy są identyczne. Dla tablicy w pytaniu (
'{null,A}'::text[]
) wynik jest zawsze PRAWDA. Czy to jest zamierzone? Dodałem kolejny test dla „IS DISTINCT FROM ALL”:Alternatywa dla standardowych operatorów
można prawie przetłumaczyć na
foo = ALL (test_arr)
daje ...TRUE
.. jeśli wszystkie elementy sąfoo
FALSE
.. jeśli jakikolwiekNOT NULL
element jest<> foo
NULL
.. jeśli przynajmniej jeden elementIS NULL
i żaden element nie jest<> foo
Tak więc pozostały przypadek narożny jest tam, gdzie
-
foo IS NULL
- i
test_arr
składa się tylko zNULL
elementów.Jeśli jedno z nich można wykluczyć, to koniec. Dlatego skorzystaj z prostego testu, jeśli
- kolumna jest zdefiniowana
NOT NULL
.- czy ty wiesz, tablica nie jest wszystkie wartości null.
W przeciwnym razie przetestuj dodatkowo:
Gdzie
'A'
i'B'
mogą być dowolne odrębne wartości. Wyjaśnienie i alternatywy w ramach tego pokrewnego pytania na temat SO:Czy tablica zawiera wszystkie wartości NULL w PostgreSQL
Ponownie, jeśli znasz dowolną wartość, która nie może istnieć
test_arr
, na przykład pusty ciąg''
, nadal możesz uprościć:Oto pełna matryca testowa do sprawdzenia wszystkich kombinacji:
Jest to nieco bardziej szczegółowe niż rozwiązanie Andriya
EXCEPT
, ale jest znacznie szybsze.źródło
OPERATOR
należy podać klauzulęCOMMUTATOR
(iNEGATOR
być może zIS NOT DISTINCT FROM
operatorem odwrotnym )? postgresql.org/docs/current/static/xoper-optimization.htmlapp_status <!> any(array[3,6])
. Niestety nie ma to żadnego wpływu na zapisy. Czy to działa z liczbami całkowitymi?