W SQL ja (niestety) często muszę używać LIKE
warunków z powodu baz danych, które naruszają prawie każdą zasadę normalizacji. Nie mogę tego teraz zmienić. Ale to nie ma znaczenia dla pytania.
Ponadto często używam warunków, takich jak WHERE something in (1,1,2,3,5,8,13,21)
lepsza czytelność i elastyczność moich instrukcji SQL.
Czy jest jakiś sposób na połączenie tych dwóch rzeczy bez pisania skomplikowanych podselekcji?
Chcę czegoś tak prostego jak WHERE something LIKE ('bla%', '%foo%', 'batz%')
zamiast tego:
WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'
Pracuję tutaj z SQl Server i Oracle, ale jestem zainteresowany, czy jest to w ogóle możliwe w dowolnym RDBMS.
like any
/like all
: stackoverflow.com/questions/40475982/sql-like-any-vs-like-all . (Dla przypomnienia, zostało to zamówione na forum Oracle Community Ideas community.oracle.com/ideas/11592 )Odpowiedzi:
Nie ma kombinacji LIKE i IN w SQL, a tym bardziej w TSQL (SQL Server) lub PLSQL (Oracle). Wynika to częściowo z tego, że wyszukiwanie pełnotekstowe (FTS) jest zalecaną alternatywą.
Zarówno implementacje FTS Oracle, jak i SQL Server obsługują słowo kluczowe CONTAINS, ale składnia jest nadal nieco inna:
Wyrocznia:
SQL Server:
Zapytana kolumna musi być indeksowana pełnotekstowo.
Odniesienie:
źródło
Jeśli chcesz, aby twoje oświadczenie było łatwe do odczytania, możesz użyć REGEXP_LIKE (dostępne od wersji Oracle 10 lub nowszej).
Przykładowa tabela:
Oryginalna składnia:
I proste zapytanie z REGEXP_LIKE
ALE ...
Nie poleciłbym tego sam ze względu na niezbyt dobre wyniki. Trzymałbym się kilku predykatów LIKE. Przykłady były więc dla zabawy.
źródło
utknąłeś z
chyba że zapełnisz tabelę tymczasową (dołącz do danych symbole wieloznaczne) i dołączysz w ten sposób:
wypróbuj (używając składni SQL Server):
WYNIK:
źródło
LIKE 'bla%'
, co w przykładowym kodzie OP? czy może tylkoLIKE '%bla%'
wyszukiwać?W PostgreSQL dostępna jest forma
ANY
lubALL
:lub
gdzie podselekcja zwraca dokładnie jedną kolumnę danych.
źródło
LIKE ANY
iLIKE ALL
wspólne dla wszystkich dialektów SQL, czyli częścią języka rdzenia lub specyficzne dla dialektu?= ANY
lub<> ALL
działa tylko w języku SQL, a nie na przykład w PLSQL.Inne rozwiązanie powinno działać na każdym RDBMS:
źródło
Sugerowałbym użycie funkcji użytkownika TableValue, jeśli chcesz enkapsulować techniki łączenia wewnętrznego lub tabeli temp. Pokazane powyżej. Pozwoliłoby to na bardziej czytelne czytanie.
Po użyciu funkcji podziału zdefiniowanej w: stronie http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx
możemy napisać następujące na podstawie utworzonej przeze mnie tabeli o nazwie „Fish” (int id, varchar (50) Name)
Wyjścia
źródło
Jednym z podejść byłoby przechowywanie warunków w tabeli tymczasowej (lub zmiennej tabeli w SQL Server) i dołączanie do tego w następujący sposób:
źródło
Zamiast tego użyj sprzężenia wewnętrznego:
źródło
Teradata obsługuje składnię LIKE ALL / ANY :
EDYTOWAĆ:
Wersja 3.12.0 jOOQ obsługuje tę składnię:
Dodaj syntetyczne [NIE] PODOBNE DO DOWOLNYCH i [NIE] PODOBNE DO WSZYSTKICH operatorów
PostgreSQL
LIKE/ILIKE ANY (ARRAY[])
:db <> demo skrzypiec
Snowflake obsługuje również dopasowanie LIKE ANY / LIKE ALL :
Przykład:
źródło
możesz nawet spróbować tego
Funkcjonować
Pytanie
źródło
Mam proste rozwiązanie, które działa co najmniej w Postgresql , używając
like any
następującej po nim listy wyrażeń regularnych. Oto przykład identyfikujący niektóre antybiotyki na liście:źródło
Zastanawiałem się również nad czymś takim. Właśnie przetestowałem przy użyciu kombinacji
SUBSTRING
iIN
jest to skuteczne rozwiązanie dla tego rodzaju problemu. Wypróbuj poniższe zapytanie:źródło
W Oracle możesz użyć kolekcji w następujący sposób:
Tutaj użyłem predefiniowanego typu kolekcji
ku$_vcnt
, ale możesz zadeklarować swój własny:źródło
W przypadku Sql Server możesz skorzystać z Dynamic SQL.
Przez większość czasu w takich sytuacjach masz parametr klauzuli IN oparty na niektórych danych z bazy danych.
Poniższy przykład jest trochę „wymuszony”, ale może pasować do różnych rzeczywistych przypadków znalezionych w starszych bazach danych.
Załóżmy, że masz w tabeli Osoby, w których nazwiska osób są przechowywane w jednym polu PersonName jako FirstName + '' + LastName. Musisz wybrać wszystkie osoby z listy imion przechowywanych w polu NameToSelect w tabeli NamesToSelect , oraz dodatkowych kryteriów (takich jak filtrowane według płci, daty urodzenia itp.)
Możesz to zrobić w następujący sposób
źródło
Mogę mieć na to rozwiązanie, chociaż o ile wiem, będzie działać tylko w SQL Server 2008. Odkryłem, że możesz użyć konstruktora wierszy opisanego w https://stackoverflow.com/a/7285095/894974, aby dołączyć do tabeli „fikcyjnej” przy użyciu klauzuli like. To brzmi bardziej skomplikowane niż jest, spójrz:
Spowoduje to, że wszyscy użytkownicy otrzymają adres e-mail, taki jak podany na liście. Mam nadzieję, że przyda się każdemu. Problemem przeszkadzało mi trochę.
źródło
Począwszy od 2016 r. SQL Server zawiera
STRING_SPLIT
funkcję . Korzystam z programu SQL Server 17.4 i mam to do pracy:źródło
Jeśli używasz MySQL, możesz uzyskać wyszukiwanie pełnotekstowe:
Wyszukiwanie pełnotekstowe, dokumentacja MySQL
źródło
Działa to w przypadku wartości oddzielonych przecinkami
Ocenia:
Jeśli chcesz używać indeksów, musisz pominąć pierwszy
'%'
znak.źródło
W Oracle RBDMS można to osiągnąć za pomocą funkcji REGEXP_LIKE .
Poniższy kod sprawdzi, czy ciąg trzeci jest obecny w wyrażeniu listy jeden | dwa | trzy | cztery | pięć (w którym symbol potoku „ | ” oznacza operację logiczną LUB).
Poprzednie wyrażenie jest równoważne z:
Więc to się uda.
Z drugiej strony następujący test zakończy się niepowodzeniem.
Istnieje kilka funkcji związanych z wyrażeniami regularnymi (REGEXP_ *) dostępnych w Oracle od wersji 10g. Jeśli jesteś programistą Oracle i interesujesz się tym tematem, powinien to być dobry początek korzystania z wyrażeń regularnych z bazą danych Oracle .
źródło
Być może uważasz, że taka kombinacja:
Jeśli zdefiniowałeś indeks pełnotekstowy dla tabeli docelowej, możesz użyć tej alternatywy:
źródło
Brak takiej odpowiedzi:
W wyroczni nie ma problemu.
źródło
W Teradata możesz użyć
LIKE ANY ('%ABC%','%PQR%','%XYZ%')
. Poniżej znajduje się przykład, który przyniósł mi takie same wynikiźródło
Wiem, że jest bardzo późno, ale miałem podobną sytuację. Potrzebowałem operatora „Like In” dla zestawu procedur przechowywanych, które mam, które akceptują wiele parametrów, a następnie używają tych parametrów do agregowania danych z wielu systemów RDBMS, więc żadne sztuczki specyficzne dla RDBMS nie działałyby, jednak procedura przechowywana i wszelkie funkcje będzie działać na MS SQL Server, więc możemy użyć T-SQL do funkcji generowania pełnych instrukcji SQL dla każdego RDBMS, ale dane wyjściowe muszą być dość niezależne od RDBMS.
To właśnie wymyśliłem na chwilę, aby zamienić ciąg znaków (taki jak parametr wchodzący do procedury składowanej) w blok SQL. Nazywam to „Licheń” dla „LIKE IN”. Zdobyć?
Liszaj.sql
Wykrywanie ogranicznika jest prawdopodobnie planowane, ale na razie domyślnie jest to średnik, więc możesz po prostu
default
tam wstawić . Prawdopodobnie są w tym błędy. Ten@leadingAnd
parametr jest tylko niewielką wartością, aby ustalić, czy chcesz wstawić przed blokiem wiodące „I”, aby dobrze pasowało do innych dodatków klauzul WHERE.Przykład użycia (z separatorem w argString)
Zwróci nvarchar (512) zawierający:
Pominie również blok, jeśli dane wejściowe nie zawierają ogranicznika:
Przykład użycia (bez separatora w argString)
Zwróci nvarchar (512) zawierający:
Mam zamiar kontynuować prace nad tym, więc jeśli coś przeoczyłem (rażąco oczywiste lub w inny sposób), prosimy o komentarz lub kontakt.
źródło
Zrób to
lub
źródło