Zum Inhalt springen

Mustervergleich

DuckDB stellt vier verschiedene Ansätze für den Mustervergleich bereit: den klassischen SQL-Operator LIKE, den neueren Operator SIMILAR TO (hinzugefügt in SQL:1999), einen Operator GLOB und POSIX-artige reguläre Ausdrücke.

LIKE

Der Ausdruck LIKE gibt true zurück, wenn die Zeichenkette dem angegebenen Muster entspricht. (Wie erwartet gibt der Ausdruck NOT LIKE false zurück, wenn LIKE true zurückgibt, und umgekehrt. Ein gleichwertiger Ausdruck ist NOT (string LIKE pattern).)

Enthält das Muster weder Prozentzeichen noch Unterstriche, steht das Muster nur für die Zeichenkette selbst; in diesem Fall verhält sich LIKE wie der Gleichheitsoperator. Ein Unterstrich (_) im Muster steht für (entspricht) ein beliebiges einzelnes Zeichen; ein Prozentzeichen (%) entspricht einer beliebigen Folge von null oder mehr Zeichen.

Der LIKE-Mustervergleich umfasst immer die gesamte Zeichenkette. Soll daher eine Folge irgendwo innerhalb einer Zeichenkette gefunden werden, muss das Muster mit einem Prozentzeichen beginnen und enden.

Einige Beispiele:

SELECT 'abc' LIKE 'abc'; -- true
SELECT 'abc' LIKE 'a%' ; -- true
SELECT 'abc' LIKE '_b_'; -- true
SELECT 'abc' LIKE 'c'; -- false
SELECT 'abc' LIKE 'c%' ; -- false
SELECT 'abc' LIKE '%c'; -- true
SELECT 'abc' NOT LIKE '%c'; -- false

Das Schlüsselwort ILIKE kann statt LIKE verwendet werden, um den Vergleich gemäß der aktiven Locale groß-/kleinschreibungsunabhängig zu machen:

SELECT 'abc' ILIKE '%C'; -- true
SELECT 'abc' NOT ILIKE '%C'; -- false

Um innerhalb einer Zeichenkette nach einem Zeichen zu suchen, das ein Platzhalter ist (% oder _), muss das Muster eine ESCAPE-Klausel und ein Escape-Zeichen verwenden, damit der Platzhalter als literales Zeichen statt als Platzhalter behandelt wird. Siehe das Beispiel unten.

Zusätzlich hat die Funktion like_escape dieselbe Funktionalität wie ein LIKE-Ausdruck mit ESCAPE-Klausel, jedoch in Funktionssyntax. Details finden Sie auf der Seite Textfunktionen.

Nach Zeichenketten mit ‘a’, dann einem literalen Prozentzeichen, dann ‘c’ suchen:

SELECT 'a%c' LIKE 'a$%c' ESCAPE '$'; -- true
SELECT 'azc' LIKE 'a$%c' ESCAPE '$'; -- false

Groß-/kleinschreibungsunabhängiges ILIKE mit ESCAPE:

SELECT 'A%c' ILIKE 'a$%c' ESCAPE '$'; -- true

Es gibt auch alternative Zeichen, die als Schlüsselwörter anstelle von LIKE-Ausdrücken verwendet werden können. Sie verbessern die PostgreSQL-Kompatibilität.

PostgreSQL-Stil LIKE-Stil
~~ LIKE
!~~ NOT LIKE
~~* ILIKE
!~~* NOT ILIKE

SIMILAR TO

Der Operator SIMILAR TO gibt wahr oder falsch zurück, je nachdem, ob das Muster der angegebenen Zeichenkette entspricht. Er ähnelt LIKE, interpretiert das Muster jedoch als regulären Ausdruck. Wie LIKE ist SIMILAR TO nur erfolgreich, wenn das Muster die gesamte Zeichenkette abdeckt; das unterscheidet sich vom üblichen Verhalten regulärer Ausdrücke, bei dem das Muster einen beliebigen Teil der Zeichenkette treffen kann.

Ein regulärer Ausdruck ist eine Zeichenfolge, die eine abgekürzte Definition einer Menge von Zeichenketten (einer regulären Menge) ist. Eine Zeichenkette entspricht einem regulären Ausdruck, wenn sie Mitglied der durch den regulären Ausdruck beschriebenen regulären Menge ist. Wie bei LIKE entsprechen Musterzeichen den Zeichen der Zeichenkette genau, sofern sie keine Sonderzeichen der Sprache der regulären Ausdrücke sind — reguläre Ausdrücke verwenden jedoch andere Sonderzeichen als LIKE.

Einige Beispiele:

SELECT 'abc' SIMILAR TO 'abc'; -- true
SELECT 'abc' SIMILAR TO 'a'; -- false
SELECT 'abc' SIMILAR TO '.*(b|d).*'; -- true
SELECT 'abc' SIMILAR TO '(b|c).*'; -- false
SELECT 'abc' NOT SIMILAR TO 'abc'; -- false

In PostgreSQL entspricht ~ SIMILAR TO und !~ entspricht NOT SIMILAR TO. In DuckDB gelten diese Entsprechungen derzeit nicht, siehe die Seite PostgreSQL-Kompatibilität.

Globbing

DuckDB unterstützt Dateinamenserweiterung, auch Globbing genannt, zum Auffinden von Dateien. Die Glob-Syntax von DuckDB verwendet das Fragezeichen (?) als Platzhalter für ein beliebiges einzelnes Zeichen und den Stern (*) für null oder mehr Zeichen. Zusätzlich können Sie die Klammersyntax ([...]) verwenden, um ein beliebiges einzelnes Zeichen zu treffen, das in den Klammern enthalten ist oder im durch die Klammern angegebenen Zeichenbereich liegt. Ein Ausrufezeichen (!) kann innerhalb der ersten Klammer verwendet werden, um nach einem Zeichen zu suchen, das nicht in den Klammern enthalten ist. Weitere Informationen finden Sie auf der Wikipedia-Seite „glob (programming)“.

GLOB

Der Operator GLOB gibt true oder false zurück, je nachdem, ob die Zeichenkette dem GLOB-Muster entspricht. Der Operator GLOB wird am häufigsten verwendet, um nach Dateinamen zu suchen, die einem bestimmten Muster folgen (zum Beispiel einer bestimmten Dateiendung).

Einige Beispiele:

SELECT 'best.txt' GLOB '*.txt'; -- true
SELECT 'best.txt' GLOB '????.txt'; -- true
SELECT 'best.txt' GLOB '?.txt'; -- false
SELECT 'best.txt' GLOB '[abc]est.txt'; -- true
SELECT 'best.txt' GLOB '[a-z]est.txt'; -- true

Die Klammersyntax ist groß-/kleinschreibungssensitiv:

SELECT 'Best.txt' GLOB '[a-z]est.txt'; -- false
SELECT 'Best.txt' GLOB '[a-zA-Z]est.txt'; -- true

Das ! gilt für alle Zeichen innerhalb der Klammern:

SELECT 'Best.txt' GLOB '[!a-zA-Z]est.txt'; -- false

Um einen GLOB-Operator zu negieren, negieren Sie den gesamten Ausdruck:

SELECT NOT 'best.txt' GLOB '*.txt'; -- false

Drei Tilden (~~~) können auch anstelle des Schlüsselworts GLOB verwendet werden.

GLOB-Stil Symbolischer Stil
GLOB ~~~

Glob-Funktion zum Finden von Dateinamen

Die Glob-Mustervergleichssyntax kann auch verwendet werden, um mit der Tabellenfunktion glob nach Dateinamen zu suchen. Sie akzeptiert einen Parameter: den zu durchsuchenden Pfad (der Glob-Muster enthalten darf).

Das aktuelle Verzeichnis nach allen Dateien durchsuchen:

SELECT * FROM glob('*');
file
duckdb.exe
test.csv
test.json
test.parquet
test2.csv
test2.parquet
todos.json

Globbing-Semantik

Die Globbing-Implementierung von DuckDB folgt der Semantik von Pythons glob und nicht dem glob der Shell. Ein bemerkenswerter Unterschied ist das Verhalten des Konstrukts **/: **/⟨filename⟩{:.language-sql .highlight} gibt eine Datei mit ⟨filename⟩{:.language-sql .highlight} im Verzeichnis der obersten Ebene nicht zurück. Mit einer vorhandenen Datei README.md im Verzeichnis findet die folgende Abfrage sie:

SELECT * FROM glob('README.md');
file
README.md

Die folgende Abfrage liefert jedoch ein leeres Ergebnis:

SELECT * FROM glob('**/README.md');

Das Globbing von Bash, Zsh usw. findet die Datei mit derselben Syntax:

Terminal window
ls **/README.md
README.md

Reguläre Ausdrücke

Die Unterstützung regulärer Ausdrücke in DuckDB ist auf der Seite Reguläre Ausdrücke dokumentiert. DuckDB unterstützt einige PostgreSQL-artige Operatoren für den Vergleich mit regulären Ausdrücken:

PostgreSQL-Stil Gleichwertiger Ausdruck
~ regexp_full_match
!~ NOT regexp_full_match
~* (nicht unterstützt)
!~* (nicht unterstützt)