FirebirdSQL logo

CASE

Verfügbar in

DSQL, PSQL

Das CASE-Konstrukt gibt einen einzigen Wert aus einer Reihe von Werten zurück.Zwei syntaktische Varianten werden unterstützt:

  • Das einfache CASE, vergleichbar zu einem CASE-Konstrukt in Pascal oder einem Switch in C

  • Das gesuchte CASE, welches wie eine Reihe aus “if …​ else if …​ else if”-Klauseln funktioniert.

Einfaches CASE
Syntax
…
CASE <test-expr>
  WHEN <expr> THEN <result>
  [WHEN <expr> THEN <result> ...]
  [ELSE <defaultresult>]
END
…

Bei dieser Variante wird test-expr mit dem ersten expr, dem zweiten expr usw. verglichen, bis eine Übereinstimmung gefunden wird und das entsprechende Ergebnis zurückgegeben wird.Wenn keine Übereinstimmung gefunden wird, wird defaultresult aus der optionalen ELSE-Klausel zurückgegeben.Wenn es keine Übereinstimmungen und keine ELSE-Klausel gibt, wird NULL zurückgegeben.

Das Matching funktioniert genauso wie der Operator “=”.Das heißt, wenn test-expr NULL ist, stimmt es mit keinem expr überein, nicht einmal mit einem Ausdruck, der in NULL aufgelöst wird.

Das zurückgegebene Ergebnis muss kein Literalwert sein: Es kann ein Feld- oder Variablenname, ein zusammengesetzter Ausdruck oder ein NULL-Literal sein.

Beispiel
SELECT
  NAME,
  AGE,
  CASE UPPER(SEX)
    WHEN 'M' THEN 'Male'
    WHEN 'F' THEN 'Female'
    ELSE 'Unknown'
  END GENDER,
RELIGION
    FROM PEOPLE

Eine Kurzform des einfachen CASE-Konstrukts wird auch in der DECODE -Funktion verwendet.

docnext count = 38

Gesuchtes CASE
Syntax
CASE
  WHEN <bool_expr> THEN <result>
  [WHEN <bool_expr> THEN <result> …]
  [ELSE <defaultresult>]
END

Der bool_expr-Ausdruck gibt ein ternäres logisches Ergebnis zurück: TRUE, FALSE oder NULL.Der erste Ausdruck, der TRUE ermittelt, wird als Ergebnis verwendet.Gibt kein Ausdruck TRUE zurück, kommt defaultresult aus der optionalen ELSE-Klausel zum Einsatz.Gibt kein Ausdruck TRUE zurück und gibt es keine ELSE-Klausel, ist der Rückgabewert NULL.

So wie im einfachen CASE-Konstrukt, muss das Ergebnis nicht zwangsläufig ein Literal sein: es kann ein Feld- oder Variablenname, ein zusammengesetzter Ausdruck oder NULL sein.

Beispiel
CANVOTE = CASE
  WHEN AGE >= 18 THEN 'Yes'
  WHEN AGE < 18 THEN 'No'
  ELSE 'Unsure'
END

NULL in Ausdrücken

NULL ist in SQL kein Wert, sondern ein state, der anzeigt, dass der Wert des Elements entweder unbekannt ist oder nicht existiert.Es ist weder eine Null, noch ein Leerzeichen, noch ein “leerer String”, und es verhält sich nicht wie ein Wert.

Wenn Sie NULL in numerischen, String- oder Datums-/Uhrzeit-Ausdrücken verwenden, ist das Ergebnis immer NULL.Wenn Sie NULL in logischen (booleschen) Ausdrücken verwenden, hängt das Ergebnis vom Typ der Operation und von anderen beteiligten Werten ab.Wenn Sie einen Wert mit NULL vergleichen, ist das Ergebnis unbekannt.

Important

NULL heißt NULL, jedoch gilt in Firebird, dass das logische Ergebnis unknown ebenfalls durch NULL repräsentiert wird.

Ausdrücke die NULL zurückgeben

Ausdrücke in dieser Liste werden immer NULL zurückgeben:

1 + 2 + 3 + NULL
'Home ' || 'sweet ' || NULL
MyField = NULL
MyField <> NULL
NULL = NULL
not (NULL)

Wenn es Ihnen schwerfällt dies zu verstehen, beachten Sie, dass NULL ein Status ist, der für “unknown” (unbekannt) steht.

NULL in logischen Ausdrücken

Es wurde bereits gezeigt, dass not (NULL) in NULL aufgeht.Dieser Effekt ist etwas komplizierter für logische AND- sowie logische OR-Operatoren:

NULL or false  → NULL
NULL or true   → true
NULL or NULL   → NULL
NULL and false → false
NULL and true  → NULL
NULL and NULL  → NULL
Tip

Als grundlegende Faustregel gilt: Wenn die Anwendung von TRUE anstelle von NULL zu einem anderen Ergebnis führt als die Anwendung von FALSE, dann ist das Ergebnis des ursprünglichen Ausdrucks unknown oder NULL.

Beispiele
(1 = NULL) or (1 <> 1)    -- Ergebnis NULL
(1 = NULL) or FALSE       -- Ergebnis NULL
(1 = NULL) or (1 = 1)     -- Ergebnis TRUE
(1 = NULL) or TRUE        -- Ergebnis TRUE
(1 = NULL) or (1 = NULL)  -- Ergebnis NULL
(1 = NULL) or UNKNOWN     -- Ergebnis NULL
(1 = NULL) and (1 <> 1)   -- Ergebnis FALSE
(1 = NULL) and FALSE      -- Ergebnis FALSE
(1 = NULL) and (1 = 1)    -- Ergebnis NULL
(1 = NULL) and TRUE       -- Ergebnis NULL
(1 = NULL) and (1 = NULL) -- Ergebnis NULL
(1 = NULL) and UNKNOWN    -- Ergebnis NULL

Unterabfragen

Eine Unterabfrage ist eine spezielle Form eines Ausdrucks, die innerhalb einer anderen Abfrage eingebettet wird.Unterabfragen werden in der gleichen Weise geschrieben wie reguläre SELECT-Abfragen, werden jedoch von Klammern umschlossen.Unterabfrage-Ausdrücke können in folgender Art und Weise verwendet werden:

  • Um eine Ausgabespalte in der SELECT-Liste anzugeben

  • Um Werte zu holen oder als Kriterium für Suchprädikate (die WHERE- und HAVING-Klauseln)

  • Um ein Set zu erstellen, das die Eltern-Abfrage verwenden kann, so als wäre dies eine reguläre Tabelle oder View.Unterabfragen wie diese erscheinen in der FROM-Klausel (Derived Tables) oder in einer Common Table Expression (CTE)

Korrelierte Unterabfragen

Eine Unterabfrage kann korreliert sein.Eine Abfrage ist korreliert, wenn die Unterabfrage und die Hauptabfrage voneinander abhängig sind.Um jeden Datensatz in der Unterabfrage zu verarbeiten, muss ein Datensatz in der Hauptabfrage abgerufen werden;d.h. die Unterabfrage hängt vollständig von der Hauptabfrage ab.

Beispiel einer korrelierten Unterabfrage
SELECT *
FROM Customers C
WHERE EXISTS
  (SELECT *
   FROM Orders O
   WHERE C.cnum = O.cnum
     AND O.adate = DATE '10.03.1990');

Werden Unterabfragen verwendet um Werte einer Ausgabespalte aus einer SELECT-Liste zu holen, muss die Unterabfrage ein skalares Ergebnis zurückliefern.

Skalare Ergebnisse

Unterabfragen, die in Suchprädikaten verwendet werden, mit Ausnahme von existenziellen und quantifizierten Prädikaten, müssen ein skalares Ergebnis zurückgeben;Das heißt, nicht mehr als eine Spalte von nicht mehr als einer passenden Zeile oder Aggregation.Sollte mehr zurückgegeben werden, wird es zu einem Laufzeitfehler kommen (“Multiple rows in a singleton select…​”).

Note

Obwohl es einen echten Fehler berichtet, kann die Nachricht etwas irreführend sein.Ein “singleton SELECT” ist eine Abfrage, die nicht mehr als eine Zeile zurückgeben kann.Jedoch sind “singleton” und “skalar” nicht gleichzusetzen: nicht alle singleton SELECTs müssen zwangsläufig skalar sein;und Einspalten-SELECTs können mehrere Zeilen für existenzielle und quantifizierte Prädikate zurückgeben.

Unterabfrage-Beispiele
  1. Eine Unterabfrage als Ausgabespalte in einer SELECT-Liste:

    SELECT
      e.first_name,
      e.last_name,
      (SELECT
           sh.new_salary
       FROM
           salary_history sh
       WHERE
           sh.emp_no = e.emp_no
       ORDER BY sh.change_date DESC ROWS 1) AS last_salary
    FROM
      employee e
  2. Eine Unterabfrage in der WHERE-Klausel, um das höchste Gehalt eines Mitarbeiters zu ermitteln und hierauf zu filtern:

    SELECT
      e.first_name,
      e.last_name,
      e.salary
    FROM employee e
    WHERE
      e.salary = (
        SELECT MAX(ie.salary)
        FROM employee ie
      )

Prädikate

Ein Prädikat ist ein einfacher Ausdruck, der eine Behauptung aufstellt, wir nennen sie P.Wenn P zu TRUE (wahr) aufgelöst wird, ist die Behauptung erfolgreich.Wird sie zu FALSE (unwahr, falsch) oder NULL (UNKNOWN) aufgelöst, ist die Behauptung falsch.Hier gibt es einen Fallstrick: Nehmen wir an, das Prädikat P gibt FALSE zurück.In diesem Falle gilt, dass NOT(P) TRUE zurückgeben wird.Andererseits gilt, falls P NULL (unknown) zurückgibt, dann gibt NOT(P) ebenfalls NULL zurück.

In SQL können Prädikate in CHECK-Einschränkungen, WHERE- und HAVING-Klauseln, CASE-Ausdrücken, der IIF()-Funktion und in der ON-Bedingung von JOIN-Klauseln und überall in einer normalen vorkommen Ausdruck auftreten kann.

Bedingungen

Eine Behauptung ist ein Statement über Daten, die, wie ein Prädikat, zu TRUE, FALSE oder NULL aufgelöst werden können.Behauptungen bestehen aus einem oder mehr Prädikaten, möglicherweise mittels NOT negiert und verbunden durch AND- sowie OR-Operatoren.Klammern können verwendet werden um Prädikate zu gruppieren und die Ausführungsreihenfolge festzulegen.

Ein Prädikat kann andere Prädikate einbetten.Die Ausführung ist nach außen gerichtet, das heißt, das innenliegendste Prädikat wird zuerst ausgeführt.Jede “Ebene” wird in ihrer Rangfolge ausgewertet bis der Wahrheitsgehalt der endgültigen Behauptung aufgelöst wird.

Vergleichs-Prädikate

Ein Vergleichsprädikat besteht aus zwei Ausdrücken, die mit einem Vergelichsoperator verbunden sind.Es existieren traditionel sechs Vergleichsoperatoren:

=, >, <, >=, <=, <>

Für die vollständige Liste der Vergleichsoperatoren mit ihren Variantenformen siehe Vergleichsoperatoren.

Wenn eine der Seiten (links oder rechts) eines Vergleichsprädikats NULL darin hat, wird der Wert des Prädikats UNKNOWN.

Beispiele
  1. Abrufen von Informationen über Computer mit der CPU-Frequenz nicht weniger als 500 MHz und der Preis niedriger als $800:

    SELECT *
    FROM Pc
    WHERE speed >= 500 AND price < 800;
  2. Abrufen von Informationen über alle Punktmatrixdrucker, die weniger als $300 kosten:

    SELECT *
    FROM Printer
    WHERE ptrtype = 'matrix' AND price < 300;
  3. Die folgende Abfrage gibt keine Daten zurück, auch nicht wenn es Drucker ohne zugewiesenen Typ gibt, da ein Prädikat, das NULL mit NULL vergleicht, NULL zurückgibt:

    SELECT *
    FROM Printer
    WHERE ptrtype = NULL AND price < 300;

    Andererseits kann ptrtype auf NULL getestet werden und ein Ergebnis zurückgeben: es ist nur kein _Vergleichstest:

    SELECT *
    FROM Printer
    WHERE ptrtype IS NULL AND price < 300;

     — Siehe auch [fblangref40-commons-isnotnull-de].

Note
Hinweis zu String-Vergleichen

Wenn die Felder CHAR und VARCHAR auf Gleichheit verglichen werden, werden abschließende Leerzeichen in allen Fällen ignoriert.

Andere Vergleichsprädikate

Andere Vergleichsprädikate werden durch Schlüsselwörter gekennzeichnet.

BETWEEN
Verfügbar in

DSQL, PSQL, ESQL

Syntax
<value> [NOT] BETWEEN <value_1> AND <value_2>

Das Prädikat BETWEEN testet, ob ein Wert in einen angegebenen Bereich von zwei Werten fällt.(NOT BETWEEN testet, ob der Wert nicht in diesen Bereich fällt.)

Die Operanden für das Prädikat BETWEEN sind zwei Argumente kompatibler Datentypen.Im Gegensatz zu einigen anderen DBMS ist das Prädikat BETWEEN in Firebird nicht symmetrisch — wenn der niedrigere Wert nicht das erste Argument ist, gibt das Prädikat BETWEEN immer FALSE zurück.Die Suche ist inklusiv (die von beiden Argumenten repräsentierten Werte werden in die Suche eingeschlossen).Mit anderen Worten, das Prädikat BETWEEN könnte umgeschrieben werden:

<value> >= <value_1> AND <value> <= <value_2>

Wenn BETWEEN in den Suchbedingungen von DML-Abfragen verwendet wird, kann der Firebird-Optimierer einen Index für die durchsuchte Spalte verwenden, falls dieser verfügbar ist.

Beispiel
SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE BETWEEN date '1992-01-01' AND CURRENT_DATE
LIKE
Verfügbar in

DSQL, PSQL, ESQL

Syntax
<match_value> [NOT] LIKE <pattern>
   [ESCAPE <escape character>]

<match_value>      ::= character-type expression
<pattern>          ::= search pattern
<escape character> ::= escape character

Das Prädikat LIKE vergleicht den zeichenartigen Ausdruck mit dem im zweiten Ausdruck definierten Muster.Die Groß-/Kleinschreibung oder Akzent-Sensitivität für den Vergleich wird durch die verwendete Kollatierung bestimmt.Bei Bedarf kann für jeden Operanden eine Kollatierung angegeben werden.

Wildcards

Zwei Wildcard-Zeichen sind für die Suche verfügbar:

  • Das Prozentzeichen (%) berücksichtigt alle Sequenzen von null oder mehr Zeichen im getesteten Wert

  • Das Unterstrichzeichen (_) berücksichtigt jedes beliebige Einzelzeichen im getesteten Wert

Wenn der getestete Wert dem Muster entspricht, unter Berücksichtigung von Wildcard-Zeichen ist das Prädikat TRUE.

Verwendung der ESCAPE-Zeichen-Option

Wenn der Such-String eines der Wildcard-Zeichen beinhaltet, kann die ESCAPE-Klausel verwendet werden, um ein Escape-Zeichen zu definieren.Das Escape-Zeichen muss im Suchstring vor dem Symbol ‘%’ oder ‘_’ stehen, um anzuzeigen, dass das Symbol als Literalzeichen interpretiert werden soll.

Beispiele für LIKE
  1. Finde die Nummern der Abteilung, deren Namen mit dem Wort “Software” starten:

    SELECT DEPT_NO
    FROM DEPT
    WHERE DEPT_NAME LIKE 'Software%';

    Es ist möglich einen Index für das Feld DEPT_NAME zu verwenden, sofern dieser existiert.

    Note
    Über LIKE und den Optimizer

    Eigentlich verwendet das LIKE-Prädikat keinen Index.Wird das Prädikat jedoch in Form von LIKE 'string%' verwendet, wird dieses zum Prädikat STARTING WITH konvertiert, welches einen Index verwendet.

    Somit gilt — wenn Sie nach einem Wortanfang suchen, sollten Sie das Prädikat STARTING WITH anstelle von LIKE verwenden.

  2. Suchen Sie nach Mitarbeitern, deren Namen aus 5 Buchstaben bestehen, mit den Buchstaben “Sm” beginnen und mit “th” enden. Das Prädikat gilt für Namen wie “Smith” und “Smyth”.

    SELECT
      first_name
    FROM
      employee
    WHERE first_name LIKE 'Sm_th'
  3. Suche nach allen Mandanten, deren Adresse den String “Rostov” enthält:

    SELECT *
    FROM CUSTOMER
    WHERE ADDRESS LIKE '%Rostov%'
    Note

    Benötigen Sie eine Suche, die Groß- und Kleinschreibung innerhalb einer Zeichenkette ignoriert (LIKE '%Abc%'), sollten Sie das CONTAINING-Prädikat, anstelle des LIKE-Prädikates, verwenden.

  4. Suchen Sie nach Tabellen, die den Unterstrich im Namen enthalten.Als Escape-Zeichen wird das Zeichen ‘#’ verwendet:

    SELECT
      RDB$RELATION_NAME
    FROM RDB$RELATIONS
    WHERE RDB$RELATION_NAME LIKE '%#_%' ESCAPE '#'
STARTING WITH
Verfügbar in

DSQL, PSQL, ESQL

Syntax
<value> [NOT] STARTING WITH <value>

Das Prädikat STARTING WITH sucht nach einer Zeichenkette oder einem zeichenkettenähnlichen Datentyp, die mit den Zeichen des Argumentes value beginnt.Die Suche unterscheidet zwischen Groß- und Kleinschreibung.

Wenn STARTING WITH als Suchkriterium in DML-Abfragen verwendet wird, nutzt der Firebird-Optimizer einen Index auf der Suchspalte, sofern vorhanden.

Beispiel

Suche nach Mitarbeitern deren Namen mit “Jo” beginnen:

SELECT LAST_NAME, FIRST_NAME
FROM EMPLOYEE
WHERE LAST_NAME STARTING WITH 'Jo'
Siehe auch

LIKE

CONTAINING
Verfügbar in

DSQL, PSQL, ESQL

Syntax
<value> [NOT] CONTAINING <value>

Das Prädikat CONTAINING sucht nach einem String oder einem stringähnlichen Typ und sucht nach der Zeichenfolge, die seinem Argument entspricht.Es kann für eine alphanumerische (stringartige) Suche nach Zahlen und Datumsangaben verwendet werden.Bei einer CONTAINING-Suche wird die Groß-/Kleinschreibung nicht beachtet.Wenn jedoch eine akzentsensitive Sortierung verwendet wird, erfolgt die Suche akzentsensitiver.

Beispiele
  1. Suche nach Projekten, deren Namen die Teilzeichenfolge “Map” enthalten:

    SELECT *
    FROM PROJECT
    WHERE PROJ_NAME CONTAINING 'Map';

    Zwei Zeilen mit den Namen “AutoMap” und “MapBrowser port” werden zurückgegeben.

  2. Suche nach Änderungen in den Gehältern, die die Zahl 84 im Datum enthalten (in diesem Falle heißt dies, Änderungen im Jahr 1984):

    SELECT *
    FROM SALARY_HISTORY
    WHERE CHANGE_DATE CONTAINING 84;
Siehe auch

LIKE

SIMILAR TO
Verfügbar in

DSQL, PSQL

Syntax
string-expression [NOT] SIMILAR TO <pattern> [ESCAPE <escape-char>]

<pattern>     ::= an SQL regular expression
<escape-char> ::= a single character

SIMILAR TO findet eine Zeichenkette anhand eines Regulären Ausdruck-Musters in SQL (engl. SQL Regular Expression Pattern).Anders als in einigen anderen Sprachen muss das Muster mit der gesamten Zeichenkette übereinstimmen, um erfolgreich zu sein — die Übereinstimmung eines Teilstrings reicht nicht aus.Ist ein Operand NULL, ist auch das Ergebnis NULL.Andernfalls ist das Ergebnis TRUE oder FALSE.

Sonderzeichen escapen

Um mit einem Sonderzeichen in regulären Ausdrücken abzugleichen, muss dieses Zeichen mit Escapezeichen versehen werden.Es gibt kein Standard-Escape-Zeichen;Stattdessen gibt der Benutzer bei Bedarf eine an:

'Peer (Poire)' similar to 'P[^ ]+ \(P[^ ]+\)' escape '\'    -- true
'Pera [Pear]'  similar to 'P[^ ]+ #[P[^ ]+#]' escape '#'    -- true
'Päron-äppledryck' similar to 'P%$-ä%' escape '$'           -- true
'Pärondryck' similar to 'P%--ä%' escape '-'                 -- false

Die letzte Zeile demonstriert, dass das Escape-Zeichen auch sich selbst escapen kann, wenn notwendig.

Syntax: SQL Reguläre Ausdrücke

Die folgende Syntax definiert das SQL-Standardausdruckformat.Es ist eine komplette und korrekte Top-down-Definition.Es ist auch sehr formell, ziemlich lang und vermutlich perfekt geeignet, jeden zu entmutigen, der nicht schon Erfahrungen mit Regulären Ausdrücken (oder mit sehr formalen, eher langen Top-down-Definitionen) gesammelt hat.Fühlen Sie sich frei, dies zu überspringen und den nächsten Abschnitt, Aufbau Regulärer Ausdrücke, zu lesen, der einen Bottom-up-Ansatz verfolgt und sich an den Rest von uns richtet.

<regular expression> ::= <regular term> ['|' <regular term> ...]

<regular term> ::= <regular factor> ...

<regular factor> ::= <regular primary> [<quantifier>]

<quantifier> ::= ? | * | + | '{' <m> [,[<n>]] '}'

<m>, <n> ::= unsigned int, mit <m> <= <n> wenn beide vorhanden

<regular primary> ::=
    <character> | <character class> | %
  | (<regular expression>)

<character> ::= <escaped character> | <non-escaped character>

<escaped character> ::=
  <escape-char> <special character> | <escape-char> <escape-char>

<special character> ::= eines der Zeichen []()|^-+*%\?{}

<non-escaped character> ::=
  ein Zeichen, das nicht ein <special character> ist
  und nicht gleich <escape-char> (wenn definiert)_

<character class> ::=
    '' | '[' <member> ... ']' | '[^' <non-member> ... ']'
  | '[' <member> ... '^' <non-member> ... ']'

<member>, <non-member> ::= <character> | <range> | <predefined class>

<range> ::= <character>-<character>

<predefined class> ::= '[:' <predefined class name> ':]'

<predefined class name> ::=
  ALPHA | UPPER | LOWER | DIGIT | ALNUM | SPACE | WHITESPACE
Aufbau Regulärer Ausdrücke

Dieser Abschnitt behandelt die Elemente und Regeln zum Aufbau Regulärer Ausdrücke in SQL.

Zeichen

Innerhalb Regulärer Ausdrücke repräsentieren die meisten Zeichen sich selbst.Die einzige Ausnahme bilden die folgenden Zeichen:

[ ] ( ) | ^ - + * % _ ? { }

... und das Escape-Zeichen, sofern definiert.

Ein Regulärer Ausdruck, der keine Sonderzeichen oder Escape-Zeichen beinhaltet, findet nur Strings, die identisch zu sich selbst sind (abhängig von der verwendeten Collation).Das heißt, es agiert wie der ‘=’-Operator:

'Apple' similar to 'Apple'  -- true
'Apples' similar to 'Apple' -- false
'Apple' similar to 'Apples' -- false
'APPLE' similar to 'Apple'  -- abhängig von der Collation
Wildcards

Die bekannten SQL-Wildcards ‘_’ und ‘%’ finden beliebige Einzelzeichen und Strings beliebiger Länge:

'Birne' similar to 'B_rne'   -- true
'Birne' similar to 'B_ne'    -- false
'Birne' similar to 'B%ne'    -- true
'Birne' similar to 'Bir%ne%' -- true
'Birne' similar to 'Birr%ne' -- false

Beachten Sie, wie ‘%’ auch den leeren String berücksichtigt.

Zeichenklassen

Ein Bündel von Zeichen, die in Klammern eingeschlossen sind, definiert eine Zeichenklasse.Ein Zeichen in der Zeichenfolge entspricht einer Klasse im Muster, wenn das Zeichen Mitglied der Klasse ist:

'Citroen' similar to 'Cit[arju]oen'     -- true
'Citroen' similar to 'Ci[tr]oen'        -- false
'Citroen' similar to 'Ci[tr][tr]oen'    -- true

Wie aus der zweiten Zeile ersichtlich ist, entspricht die Klasse nur einem einzigen Zeichen, nicht einer Sequenz.

Innerhalb einer Klassendefinition definieren zwei Zeichen, die durch einen Bindestrich verbunden sind, einen Bereich.Ein Bereich umfasst die beiden Endpunkte und alle Zeichen, die zwischen ihnen in der aktiven Sortierung liegen.Bereiche können überall in der Klassendefinition ohne spezielle Begrenzer platziert werden, um sie von den anderen Elementen zu trennen.

'Datte' similar to 'Dat[q-u]e'          -- true
'Datte' similar to 'Dat[abq-uy]e'       -- true
'Datte' similar to 'Dat[bcg-km-pwz]e'   -- false
Vordefinierte Zeichenklassen

Die folgenden vordefinierten Zeichenklassen können auch in einer Klassendefinition verwendet werden:

[:ALPHA:]

Lateinische Buchstaben a..z und A..Z.Mit einer akzentunempfindlichen Sortierung stimmt diese Klasse auch mit akzentuierten Formen dieser Zeichen überein.

[:DIGIT:]

Dezimalziffern 0..9.

[:ALNUM:]

Gesamtheit aus [:ALPHA:] und [:DIGIT:].

[:UPPER:]

Großgeschriebene Form der lateinischen Buchstaben A..Z.Findet auch kleingeschriebene Strings mit groß- und kleinschreibunempfindlicher Collation sowie akzentunempfindlicher Collation.

[:LOWER:]

Kleingeschriebene Form der lateinischen Buchstaben A..Z.Findet auch großgeschriebene Strings mit groß- und kleinschreibunempfindlicher Collation sowie akzentunempfindlicher Collation.

[:SPACE:]

Findet das Leerzeichen (ASCII 32).

[:WHITESPACE:]

Findet horizontalen Tabulator (ASCII 9), Zeilenvorschub (ASCII 10), vertikalen Tabulator (ASCII 11), Seitenvorschub (ASCII 12), Wagenrücklauf (ASCII 13) und Leerzeichen (ASCII 32).

Das Einbinden einer vordefinierten Klasse hat den gleichen Effekt wie das Einbinden all seiner Mitglieder.Vordefinierte Klassen sind nur in Klassendefinitionen erlaubt.Wenn Sie gegen eine vordefinierte Klasse prüfen und gegen nichts sonst, platzieren Sie ein zusätzliches Paar von Klammern um sie herum.

'Erdbeere' similar to 'Erd[[:ALNUM:]]eere'     -- true
'Erdbeere' similar to 'Erd[[:DIGIT:]]eere'     -- false
'Erdbeere' similar to 'Erd[a[:SPACE:]b]eere'   -- true
'Erdbeere' similar to [[:ALPHA:]]              -- false
'E'        similar to [[:ALPHA:]]              -- true

Wenn eine Klassendefinition mit einem Caret-Zeichen beginnt, wird alles, was folgt, aus der Klasse ausgeschlossen.Alle anderen Zeichen stimmen überein:

'Framboise' similar to 'Fra[^ck-p]boise'       -- false
'Framboise' similar to 'Fr[^a][^a]boise'       -- false
'Framboise' similar to 'Fra[^[:DIGIT:]]boise'  -- true

If the caret is not placed at the start of the sequence, the class contains everything before the caret, except for the elements that also occur after the caret:

'Grapefruit' similar to 'Grap[a-m^f-i]fruit'   -- true
'Grapefruit' similar to 'Grap[abc^xyz]fruit'   -- false
'Grapefruit' similar to 'Grap[abc^de]fruit'    -- false
'Grapefruit' similar to 'Grap[abe^de]fruit'    -- false

'3' similar to '[[:DIGIT:]^4-8]'               -- true
'6' similar to '[[:DIGIT:]^4-8]'               -- false

Zuletzt sei noch erwähnt, dass die Wildcard-Zeichen ‘_’ eine eigene Zeichenklasse sind, die einem beliebigen einzelnen Zeichen entspricht.

Bezeichner

Ein Fragezeichen, direkt von einem weiteren Zeichen oder Klasse gefolgt, gibt an, dass das folgende Element gar nicht oder einmalig vorkommen darf:

'Hallon' similar to 'Hal?on'                   -- false
'Hallon' similar to 'Hal?lon'                  -- true
'Hallon' similar to 'Halll?on'                 -- true
'Hallon' similar to 'Hallll?on'                -- false
'Hallon' similar to 'Halx?lon'                 -- true
'Hallon' similar to 'H[a-c]?llon[x-z]?'        -- true

Ein Sternchen (‘*’) unmittelbar nach einem Zeichen oder einer Klasse zeigt an, dass das vorangehende Element 0-mal oder öfter vorkommen kann, damit es übereinstimmt:

'Icaque' similar to 'Ica*que'                  -- true
'Icaque' similar to 'Icar*que'                 -- true
'Icaque' similar to 'I[a-c]*que'               -- true
'Icaque' similar to '_*'                       -- true
'Icaque' similar to '[[:ALPHA:]]*'             -- true
'Icaque' similar to 'Ica[xyz]*e'               -- false

Ein Pluszeichen (‘+’) unmittelbar nach einem Zeichen oder einer Klasse gibt an, dass das vorangehende Element mindestens einmal vorkommen muss, damit es übereinstimmt:

'Jujube' similar to 'Ju_+'                     -- true
'Jujube' similar to 'Ju+jube'                  -- true
'Jujube' similar to 'Jujuber+'                 -- false
'Jujube' similar to 'J[jux]+be'                -- true
'Jujube' sililar to 'J[[:DIGIT:]]+ujube'       -- false

Wenn auf ein Zeichen oder eine Klasse eine Zahl in geschweiften Klammern folgt (‘{’ und ‘}’), muss sie genau so oft wiederholt werden, damit sie übereinstimmt:

'Kiwi' similar to 'Ki{2}wi'                    -- false
'Kiwi' similar to 'K[ipw]{2}i'                 -- true
'Kiwi' similar to 'K[ipw]{2}'                  -- false
'Kiwi' similar to 'K[ipw]{3}'                  -- true

Wenn der Zahl ein Komma folgt (‘,’), muss das Element mindestens so oft wiederholt werden, damit es übereinstimmt:

'Limone' similar to 'Li{2,}mone'               -- false
'Limone' similar to 'Li{1,}mone'               -- true
'Limone' similar to 'Li[nezom]{2,}'            -- true

Wenn die geschweiften Klammern zwei durch ein Komma getrennte Zahlen enthalten, wobei die zweite Zahl nicht kleiner als die erste ist, muss das Element mindestens die erste Zahl und höchstens die zweite Zahl wiederholt werden, um zu entsprechen:

'Mandarijn' similar to 'M[a-p]{2,5}rijn'       -- true
'Mandarijn' similar to 'M[a-p]{2,3}rijn'       -- false
'Mandarijn' similar to 'M[a-p]{2,3}arijn'      -- true

Die Bezeichner ‘?’, ‘*’ und ‘+’ sind Kurzschreibweisen für {0,1}, {0,} und {1,}.

Oder-verknüpfte Terme

Reguläre Ausdrücke können Oder-verknüpft werden mittels ‘|’-Operator.Eine Gesamtübereinstimmung tritt auf, wenn die Argumentzeichenkette mit mindestens einem Term übereinstimmt.

'Nektarin' similar to 'Nek|tarin'              -- false
'Nektarin' similar to 'Nektarin|Persika'       -- true
'Nektarin' similar to 'M_+|N_+|P_+'            -- true
Unterausdrücke

Ein oder mehrere Teile der regulären Ausdrücke können in Unterausdrücke gruppiert werden (auch Untermuster genannt), indem diese in runde Klammern eingeschlossen werden.Ein Unterausdruck ist ein eigener regulärer Ausdruck.Dieser kann alle erlaubten Elemente eines regulären Ausdrucks enthalten, und auch eigene Bezeichner.

'Orange' similar to 'O(ra|ri|ro)nge'           -- true
'Orange' similar to 'O(r[a-e])+nge'            -- true
'Orange' similar to 'O(ra){2,4}nge'            -- false
'Orange' similar to 'O(r(an|in)g|rong)?e'      -- true
IS [NOT] DISTINCT FROM
Verfügbar in

DSQL, PSQL

Syntax
<operand1> IS [NOT] DISTINCT FROM <operand2>

Zwei Operanden werden als DISTINCT angesehen, wenn sie unterschiedliche Werte besitzen oder wenn einer NULL ist und der andere nicht-NULL.Sie werden als NOT DISTINCT angesehen, wenn sie den gleichen Wert besitzen oder beide Operanden NULL sind.

IS [NOT] DISTINCT FROM liefert immer TRUE oder FALSE und niemals UNKNOWN (NULL) (unbekannter Wert).Die Operatoren ‘=’ und ‘<>’ geben umgekehrt UNKNOWN (NULL) zurück, wenn einer oder beide Operanden NULL sind.

Table 1. Ergebnisse verschiedener Vergleichsprädikate

Operandenwerte

Ergebnis verschiedener Prädikate

=

IS NOT DISTINCT FROM

<>

IS DISTINCT FROM

Gleiche Werte

TRUE

TRUE

FALSE

FALSE

Verschiedene Werte

FALSE

FALSE

TRUE

TRUE

Beide NULL

UNKNOWN

TRUE

UNKNOWN

FALSE

Einer NULL, einer nicht-NULL

UNKNOWN

FALSE

UNKNOWN

TRUE

Beispiele
SELECT ID, NAME, TEACHER
FROM COURSES
WHERE START_DAY IS NOT DISTINCT FROM END_DAY;

-- PSQL-Fragment
IF (NEW.JOB IS DISTINCT FROM OLD.JOB)
THEN POST_EVENT 'JOB_CHANGED';
Boolesches IS [NOT]
Verfügbar in

DSQL, PSQL

Syntax
<value> IS [NOT] { TRUE | FALSE | UNKNOWN }

Das IS-Prädikat mit booleschen Literalwerten prüft, ob der Ausdruck auf der linken Seite mit dem booleschen Wert auf der rechten Seite übereinstimmt.Der Ausdruck auf der linken Seite muss vom Typ BOOLEAN sein, sonst kommt es zu einer Ausnahme.

Das IS [NOT] UNKNOWN entspricht IS [NOT] NULL.

Note

Die rechte Seite des Prädikats akzeptiert nur die Literale TRUE, FALSE und UNKNOWN (und NULL).Es akzeptiert keine Ausdrücke.

Verwenden des IS-Prädikats mit einem booleschen Datentyp
-- FALSE-Wert prüfen
SELECT * FROM TBOOL WHERE BVAL IS FALSE;

ID            BVAL
============= =======
2             <false>

-- UNKNOWN-Wert prüfen
SELECT * FROM TBOOL WHERE BVAL IS UNKNOWN;

ID            BVAL
============= =======
3             <null>
IS [NOT] NULL
Verfügbar in

DSQL, PSQL, ESQL

Syntax
<value> IS [NOT] NULL

Da NULL kein Wert ist, sind diese Operatoren keine Vergleichsoperatoren.Das Prädikat IS [NOT] NULL prüft die Behauptung, dass der Ausdruck auf der linken Seite einen Wert (IS NOT NULL) oder keinen Wert hat (IS NULL).

Beispiel

Suche nach Verkäufen, die kein Versanddatum besitzen:

SELECT * FROM SALES
WHERE SHIP_DATE IS NULL;
Note
Hinweis bezüglich des IS-Prädikates

Bis einschließlich Firebird 2.5, hat das Prädikat IS, wie andere Vergleichsprädikate, keinen Vorrang gegenüber anderer.Ab Firebird 3.0 hat dieses Prädikat Vorrang gegenüber den anderen.

Existenzprädikate

Diese Gruppe von Prädikaten umfasst diejenigen, die Unterabfragen verwenden, um Werte für alle Arten von Zusicherungen in Suchbedingungen zu übermitteln.Existenzielle Prädikate werden so genannt, weil sie verschiedene Methoden verwenden, um auf existence oder non-existence einer Bedingung zu testen, und TRUE zurückgeben, wenn die Existenz oder Nichtexistenz bestätigt wird oder FALSE andernfalls.

EXISTS

Verfügbar in

DSQL, PSQL, ESQL

Syntax
[NOT] EXISTS (<select_stmt>)

Das Prädikat EXISTS verwendet als Argument einen Unterabfrageausdruck.Es gibt TRUE zurück, wenn das Ergebnis der Unterabfrage mindestens eine Zeile enthalten würde; andernfalls gibt es FALSE zurück.

NOT EXISTS gibt FALSE zurück, wenn das Ergebnis der Unterabfrage mindestens eine Zeile enthalten würde; andernfalls gibt es TRUE zurück.

Note

Die Unterabfrage kann mehrere Spalten enthalten, oder SELECT *, da die Prüfung anhand der zurückgegebenen Datenzeilen vorgenommen wird, die die Bedingungen erfüllen.

Beispiele
  1. Finde die Mitarbeiter, die Projekte haben.

    SELECT *
    FROM employee
    WHERE EXISTS(SELECT *
                 FROM  employee_project ep
                 WHERE ep.emp_no = employee.emp_no)
  2. Finde die Mitarbeiter, die keine Projekte haben.

    SELECT *
    FROM employee
    WHERE NOT EXISTS(SELECT *
                     FROM employee_project ep
                     WHERE ep.emp_no = employee.emp_no)

IN

Verfügbar in

DSQL, PSQL, ESQL

Syntax
<value> [NOT] IN (<select_stmt> | <value_list>)

<value_list> ::= <value_1> [, <value_2> …]

Das Prädikat IN prüft, ob der Wert des Ausdrucks auf der linken Seite im Wertesatz der rechten Seite vorkommt.Der Wertesatz darf nicht mehr als 1500 Elemente enthalten.Das IN-Prädikat kann mit folgender äquivalenter Form ersetzt werden:

(<value> = <value_1> [OR <value> = <value_2> …])

<value> = { ANY | SOME } (<select_stmt>)

Wenn das Prädikat IN als Suchbedingung in DML-Abfragen verwendet wird, kann der Firebird-Optimizer einen Index auf die Suchspalte nutzen, sofern einer vorhanden ist.

In seiner zweiten Form prüft das Prädikat IN, ob der linke Ausdruckswert im Ergebnis der Unterabfrage vorhanden ist (oder nicht vorhanden, wenn NOT IN verwendet wird).

Die Unterabfrage darf nur eine Spalte abfragen, andernfalls wird es zum Fehler “count of column list and variable list do not match” kommen.

Abfragen, die das Prädikat IN mit einer Unterabfrage verwenden, können durch eine ähnliche Abfrage mittels des EXISTS-Prädikates ersetzt werden.Zum Beispiel folgende Abfrage:

SELECT
  model, speed, hd
FROM PC
WHERE
model IN (SELECT model
          FROM product
          WHERE maker = 'A');

kann ersetzt werden mittels EXISTS-Prädikat:

SELECT
  model, speed, hd
FROM PC
WHERE
 EXISTS (SELECT *
         FROM product
         WHERE maker = 'A'
           AND product.model = PC.model);

Jedoch gilt zu beachten, dass eine Abfrage mittels NOT IN und einer Unterabfrage nicht immer das gleiche Ergebnis zurückliefert wie sein Gegenpart mit NOT EXISTS.Dies liegt daran, dass EXISTS immer TRUE oder FALSE zurückgibt, wohingegen IN NULL in diesen beiden Fällen zurückliefert:

  1. wenn der geprüfte Wert NULL ist und die IN ()-Liste nicht leer ist

  2. wenn der geprüfte Wert keinen Treffer in der IN ()-Liste enthält und mindestens ein Element NULL ist.

Nur in diesen beiden Fällen wird IN () NULL zurückgeben, während das EXISTS-Prädikat FALSE zurückgibt ('keine passende Zeile gefunden', engl. 'no matching row found').In einer Suche oder, zum Beispiel in einem IF (…​)-Statement, bedeuten beide Ergebnisse einen “Fehler” und es macht damit keinen Unterschied.

Aber für die gleichen Daten gibt NOT IN () NULL zurück, während NOT EXISTS TRUE zurückgibt, was das Gegenteilige Ergebnis ist.

Schauen wir uns das folgendes Beispiel an:

-- Suche nach Bürgern die nicht am gleichen Tag wie eine
-- berühmte New Yorker Persönlichkeit geboren wurden
SELECT P1.name AS NAME
FROM Personnel P1
WHERE P1.birthday NOT IN (SELECT C1.birthday
                          FROM Celebrities C1
                          WHERE C1.birthcity = 'New York');

Nehmen wir nun an, dass die Liste der New Yorker Berühmtheiten nicht leer ist und mindestens einen NULL-Geburtstag aufweist.Dann gilt für alle Bürger, die nicht am gleichen Tag mit einer Berühmtheit Geburtstag haben, dass NOT IN NULL zurückgibt, da dies genau das ist was IN tut.Die Suchbedingung wurde nicht erfüllt und die Bürger werden nicht im Ergebnis des SELECT berücksichtigt, da die Aussage falsch ist.

Bürger, die am gleichen Tag wie eine Berühmtheit Geburtstag feiern, wird NOT IN korrekterweise FALSE zurückgeben, womit diese ebenfalls aussortiert werden, und damit keine Zeile zurückgegeben wird.

Wird die Form NOT EXISTS verwendet:

-- Suche nach Bürgern, die nicht am gleichen Tag wie eine
-- berühmte New Yorker Persönlichkeit geboren wurden
SELECT P1.name AS NAME
FROM Personnel P1
WHERE NOT EXISTS (SELECT *
                  FROM Celebrities C1
                  WHERE C1.birthcity = 'New York'
                    AND C1.birthday = P1.birthday);

nicht-Übereinstimmungen werden im NOT EXISTS-Ergebnis TRUE erhalten und ihre Datensätze landen im Rückgabesatz.

Tip

Wenn bei der Suche nach einer Nichtübereinstimmung die Möglichkeit besteht, dass NULL gefunden wird, sollten Sie NOT EXISTS verwenden.

Beispiele für die Verwendung
  1. Finde Mitarbeiter mit den Namen “Pete”, “Ann” und “Roger”:

    SELECT *
    FROM EMPLOYEE
    WHERE FIRST_NAME IN ('Pete', 'Ann', 'Roger');
  2. Finde alle Computer, die deren Hersteller mit dem Buchstaben “A” beginnt:

    SELECT
      model, speed, hd
    FROM PC
    WHERE
      model IN (SELECT model
                FROM product
                WHERE maker STARTING WITH 'A');
Siehe auch

EXISTS

SINGULAR

Verfügbar in

DSQL, PSQL, ESQL

Syntax
[NOT] SINGULAR (<select_stmt>)

Das Prädikat SINGULAR nimmt eine Unterabfrage als Argument und wertet sie als TRUE, wenn die Unterabfrage genau eine Ergebniszeile zurückgibt; andernfalls wird das Prädikat als FALSE ausgewertet.Die Unterabfrage kann mehrere Ausgabespalten auflisten, da die Zeilen sowieso nicht zurückgegeben werden.Sie werden nur auf (singuläre) Existenz geprüft.Der Kürze halber wird normalerweise ‘SELECT *’ angegeben.Das Prädikat SINGULAR kann nur zwei Werte zurückgeben: TRUE oder FALSE.

Beispiel

Finden Sie die Mitarbeiter, die nur ein Projekt haben.

SELECT *
FROM employee
WHERE SINGULAR(SELECT *
               FROM employee_project ep
               WHERE ep.emp_no = employee.emp_no)

Quantifizierte Unterabfrage-Prädikate

Ein Quantifizierer ist ein logischer Operator, der die Anzahl der Objekte festlegt, für die diese Behauptung wahr ist.Es ist keine numerische Größe, sondern eine logische, die die Behauptung mit dem vollen Satz möglicher Objekte verbindet.Solche Prädikate basieren auf logischen universellen und existentiellen Quantifizierern, die in der formalen Logik erkannt werden.

In Unterabfrageausdrücken ermöglichen quantifizierte Prädikate den Vergleich einzelner Werte mit den Ergebnissen von Unterabfragen;sie haben die folgende gemeinsame Form:

<value expression> <comparison operator> <quantifier> <subquery>

ALL

Verfügbar in

DSQL, PSQL, ESQL

Syntax
<value> <op> ALL (<select_stmt>)

Wenn der ALL-Quantifizierer verwendet wird, ist das Prädikat TRUE, wenn jeder Wert, der von der Unterabfrage zurückgegeben wird, die Bedingung des Prädikates in der Hauptabfrage erfüllt ist.

Beispiel

Zeige nur jene Kunden an, deren Bewertungen höher sind als die Bewertung jedes Kunden in Paris.

SELECT c1.*
FROM Customers c1
WHERE c1.rating > ALL
      (SELECT c2.rating
       FROM Customers c2
       WHERE c2.city = 'Paris')
Important

Wenn die Unterabfrage einen leeren Satz zurückgibt, ist das Prädikat TRUE für jeden linken Wert, unabhängig vom Operator.Dies mag widersprüchlich erscheinen, denn jeder linke Wert wird gegenüber dem rechten betrachtet als: kleiner als, größer als, gleich sowie ungleich.

Dennoch passt dies perfekt in die formale Logik: Wenn der Satz leer ist, ist das Prädikat 0 mal wahr, d.h. für jede Zeile im Satz.

ANY and SOME

Verfügbar in

DSQL, PSQL, ESQL

Syntax
<value> <op> {ANY | SOME} (<select_stmt>)

Die Quantifizierer ANY und SOME sind in ihrem Verhalten identisch.Offensichtlich sind beide im SQL-Standard vorhanden, so dass sie austauschbar verwendet werden können, um die Lesbarkeit der Operatoren zu verbessern.Wird der ANY- oder SOME-Quantifizierer verwendet, ist das Prädikat TRUE, wenn einer der zurückgegebenen Werte der Unterabfrage die Suchbedingung der Hauptabfrage erfüllt.Gibt die Unterabfrage keine Zeile zurück, wird das Prädikat automtisch als FALSE angesehen.

Beispiel

Zeige nur die Kunden, deren Bewertungen höher sind als die eines oder mehrerer Kunden in Rom.

SELECT *
FROM Customers
WHERE rating > ANY
      (SELECT rating
       FROM Customers
       WHERE city = 'Rome')