452 Stimmen

Gibt es eine Kombination von "LIKE" und "IN" in SQL?

In SQL muss ich (leider) oft "LIKE"-Bedingungen verwenden, aufgrund von Datenbanken, die nahezu alle Regeln der Normalisierung verletzen. Das kann ich im Moment nicht ändern. Aber das ist irrelevant für die Frage.

Weiterhin verwende ich oft Bedingungen wie WHERE etwas in (1,1,2,3,5,8,13,21) für bessere Lesbarkeit und Flexibilität meiner SQL-Anweisungen.

Gibt es eine mögliche Möglichkeit, diese beiden Dinge ohne das Schreiben von komplizierten Unterabfragen zu kombinieren?

Ich möchte etwas so Einfaches wie WHERE etwas LIKE ('bla%', '%foo%', 'batz%') anstelle von diesem:

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

Ich arbeite hier mit SQL Server und Oracle, aber ich bin interessiert, ob dies überhaupt in einem RDBMS möglich ist.

1 Stimmen

Du musst tun und mögen oder: UND (etwas WIE '%Ding%' oder etwas WIE '%Ding%' oder etwas WIE '%Ding%')

1 Stimmen

Ich wünschte, wir hätten Teradatas like any / like all: stackoverflow.com/questions/40475982/sql-like-any-vs-like-al‌​l. (Zur Erinnerung, dies wurde im Oracle Community Ideas-Forum angefordert community.oracle.com/ideas/11592)

0 Stimmen

3voto

mik Punkte 3076

In Oracle können Sie eine Sammlung auf folgende Weise verwenden:

WHERE EXISTS (SELECT 1
                FROM TABLE(ku$_vcnt('bla%', '%foo%', 'batz%'))
               WHERE something LIKE column_value)

Hier habe ich einen vordefinierten Sammlungstyp ku$_vcnt verwendet, aber Sie können Ihren eigenen wie folgt deklarieren:

CREATE TYPE my_collection AS TABLE OF VARCHAR2(4000);

1voto

bzamfir Punkte 4490

Für Sql Server können Sie auf Dynamic SQL zurückgreifen.

In den meisten Fällen haben Sie in solchen Situationen den Parameter der IN-Klausel basierend auf einigen Daten aus der Datenbank.

Das folgende Beispiel ist ein wenig "erzwungen", aber dies kann verschiedenen realen Fällen in Legacy-Datenbanken entsprechen.

Angenommen, Sie haben die Tabelle Personen, in der Personennamen in einem einzelnen Feld PersonenName als Vorname + ' ' + Nachname gespeichert sind. Sie müssen alle Personen aus einer Liste von Vornamen auswählen, die im Feld NameToSelect in der Tabelle NamesToSelect gespeichert sind, zusammen mit einigen zusätzlichen Kriterien (wie Filterung nach Geschlecht, Geburtsdatum usw.).

Sie können dies wie folgt tun

-- @gender ist nchar(1), @birthDate ist Date 

declare 
  @sql nvarchar(MAX),
  @subWhere nvarchar(MAX),
  @params nvarchar(MAX)

-- Bereiten Sie die WHERE-Teilbedingung vor, um LIKE IN (...) zu decken
-- es wird tatsächlich Where-Klausel PersonName Like 'param1%' or PersonName Like 'param2%' or ... erstellen
set @subWhere = STUFF(
  (
    SELECT ' OR PersonName like ''' + [NameToSelect] + '%''' 
        FROM [NamesToSelect] t FOR XML PATH('')
  ), 1, 4, '')

-- Erstellen des dynamischen SQL
set @sql ='select 
      PersonName
      ,Geschlecht
      ,Geburtsdatum    -- und andere Felder hier         
  from [Persons]
  where 
    Geschlecht = @gender
    AND Geburtsdatum = @birthDate
    AND (' + @subWhere + ')'

set @params = ' @gender nchar(1),
  @birthDate Date'     

EXECUTE sp_executesql @sql, @params,    
  @gender,  
  @birthDate

1voto

abrittaf Punkte 547

In Oracle RBDMS können Sie dieses Verhalten mit der REGEXP_LIKE Funktion erreichen.

Der folgende Code testet, ob der String drei im Listen-Ausdruck eins|zwei|drei|vier|fünf vorhanden ist (wobei das Pipe-Symbol "|" die ODER-Logikoperation bedeutet).

SELECT 'Erfolg !!!' result
FROM dual
WHERE REGEXP_LIKE('drei', 'eins|zwei|drei|vier|fünf');

RESULT
---------------------------------
Erfolg !!!

1 Zeile ausgewählt.

Der vorherige Ausdruck ist äquivalent zu:

drei=eins ODER drei=zwei ODER drei=drei ODER drei=vier ODER drei=fünf

Also wird es erfolgreich sein.

Andererseits wird der folgende Test fehlschlagen.

SELECT 'Erfolg !!!' result
FROM dual
WHERE REGEXP_LIKE('zehn', 'eins|zwei|drei|vier|fünf');

keine Zeilen ausgewählt

Es gibt mehrere Funktionen im Zusammenhang mit regulären Ausdrücken (REGEXP_*) verfügbar in Oracle seit der Version 10g. Wenn Sie ein Oracle-Entwickler sind und an diesem Thema interessiert sind, könnte dies ein guter Anfang sein: Verwenden von regulären Ausdrücken mit der Oracle-Datenbank.

1voto

David F Mayer Punkte 11

Dies funktioniert für durch Kommas getrennte Werte

DECLARE @ARC_CHECKNUM VARCHAR(MAX)
SET @ARC_CHECKNUM = 'ABC,135,MED,ASFSDFSF,AXX'
SELECT ' AND (a.arc_checknum LIKE ''%' + REPLACE(@arc_checknum,',','%'' OR a.arc_checknum LIKE ''%') + '%'')''

Wird ausgewertet zu:

 AND (a.arc_checknum LIKE '%ABC%' OR a.arc_checknum LIKE '%135%' OR a.arc_checknum LIKE '%MED%' OR a.arc_checknum LIKE '%ASFSDFSF%' OR a.arc_checknum LIKE '%AXX%')

Wenn Sie möchten, dass Indizes verwendet werden, müssen Sie das erste '%' Zeichen weglassen.

1voto

chris Punkte 717

Wenn Sie MySQL verwenden, ist die nächstbeste Option die Volltextsuche:

Volltextsuche, MySQL-Dokumentation

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X