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

11voto

Lukasz Szozda Punkte 137580

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

Teradata unterstützt die Syntax LIKE ALL/ANY:

ALL jedes Element in der Liste.
ANY irgendein Element in der Liste.

      Diese Ausdrücke sind äquivalent ... 

 x LIKE ALL ('A%','%B','%C%')  x LIKE 'A%'                        
                               UND x LIKE '%B'                    
                               UND x LIKE '%C%'                   

 x LIKE ANY ('A%','%B','%C%')  x LIKE 'A%'                        
                               ODER x LIKE '%B'                    
                               ODER x LIKE '%C%'                    

EDIT:

jOOQ Version 3.12.0 unterstützt diese Syntax:

Synthetische [NICHT] LIKE ANY und [NICHT] LIKE ALL Operatoren hinzufügen

Oftmals möchten SQL-Benutzer LIKE- und IN-Prädikate kombinieren, wie in:

SELECT *
FROM customer
WHERE last_name [ NICHT ] LIKE ANY ('A%', 'E%') [ ESCAPE '!' ]

Der Workaround besteht darin, das Prädikat manuell zu erweitern, um dem Äquivalent zu entsprechen

SELECT *
FROM customer
WHERE last_name LIKE 'A%'
ODER last_name LIKE 'E%'

jOOQ könnte ein solches synthetisches Prädikat von Haus aus unterstützen.


PostgreSQL LIKE/ILIKE ANY (ARRAY[]):

SELECT *
FROM t
WHERE c LIKE ANY (ARRAY['A%', '%B']);

SELECT *
FROM t
WHERE c LIKE ANY ('{"Do%", "%at"}');

db<>fiddle Demo


Snowflake unterstützt auch das Übereinstimmen mit LIKE ANY/LIKE ALL:

LIKE ANY/ALL

Ermöglicht das case-sensitive Abgleichen von Zeichenfolgen basierend auf dem Vergleich mit einem oder mehreren Mustern.

 LIKE ANY ( [,  ... ] ) [ ESCAPE  ]

Beispiel:

SELECT * 
FROM like_example 
WHERE subject LIKE ANY ('%Jo%oe%','T%e')
-- WHERE subject LIKE ALL ('%Jo%oe%','J%e')

11voto

Famous Nerd Punkte 406

Ich würde empfehlen, die Benutzerfunktion TableValue zu verwenden, wenn Sie den Inner Join oder die Temp-Tabellentechniken wie oben gezeigt zusammenfassen möchten. Dadurch wird der Code etwas übersichtlicher.

Nach Verwendung der Split-Funktion, die definiert ist unter: http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx

können wir folgendes basierend auf einer von mir erstellten Tabelle namens "Fish" (int id, varchar(50) Name) schreiben

SELECT Fish.* from Fish 
    JOIN dbo.Split('%ass,%e%',',') as Splits 
    on Name like Splits.items  //items ist der Name der Ausgabespalte aus der Split-Funktion.

Ausgaben

1   Bass
2   Pike
7   Angler
8   Walleye

1 Stimmen

Ein Datensatz wird dupliziert, wenn er gleichzeitig mehreren Bedingungen entspricht.

8voto

A-K Punkte 16460

Verwenden Sie stattdessen einen Inner Join:

SELECT ...
FROM SomeTable
JOIN
(SELECT 'bla%' AS Pattern 
UNION ALL SELECT '%foo%'
UNION ALL SELECT 'batz%'
UNION ALL SELECT 'abc'
) AS Patterns
ON SomeTable.SomeColumn LIKE Patterns.Pattern

1 Stimmen

Nun, das ist genau das, was ich vermeiden möchte. Obwohl es funktioniert.

0 Stimmen

Warum sollte man diese Lösung vermeiden? Es funktioniert genauso schnell wie die akzeptierte Lösung und ist genauso vielseitig.

3 Stimmen

@PhilFactor Diese Lösung kann doppelte Zeilen erstellen.

7voto

AdaTheDev Punkte 135097

Ein Ansatz wäre, die Bedingungen in einer temporären Tabelle (oder Tabellenvariable in SQL Server) zu speichern und dann wie folgt damit zu verknüpfen:

SELECT t.SomeField
FROM YourTable t
   JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue

0 Stimmen

Eine Zeile wird dupliziert, wenn sie gleichzeitig von mehreren Bedingungen erfüllt wird.

6voto

Mark Punkte 1007

Ab 2016 enthält SQL Server eine STRING_SPLIT Funktion. Ich verwende SQL Server v17.4 und habe das für mich zum Laufen gebracht:

DECLARE @dashboard nvarchar(50)
SET @dashboard = 'P1%,P7%'

SELECT * from Project p
JOIN STRING_SPLIT(@dashboard, ',') AS sp ON p.ProjectNumber LIKE sp.value

0 Stimmen

Sollte wirklich where exists (select 1 from STRING_SPLIT(...) sp(value) where p.ProjectNumber LIKE sp.value) ) verwendet werden. Bei Verwendung eines Joins werden mehrere Zeilen zurückgegeben, wenn mehrere Muster übereinstimmen.

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