Firebird Documentation IndexFirebird 2.5 SprachreferenzAllgemeine Sprachelemente → Prädikate
Firebird Home Firebird Home Zurück: AusdrückeFirebird Documentation IndexNach oben: Allgemeine SprachelementeWeiter: Statements der Data Definition (DDL)

Prädikate

Inhaltsverzeichnis

Behauptungen
Vergleichs-Prädikate
Existenzprädikate
Quantifizierte Unterabfrage-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-Constraints auftreten, WHERE- und HAVING-Klauseln, CASE-Ausdrücken, der IIF()-Funktion und in der ON-Bedingung der JOIN-Klausel.

Behauptungen

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 ODER-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

Inhaltsverzeichnis

Andere Vergleichsprä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;
                
    Auf der anderen Seite kann ptrtype auf NULL getestet werden; mit dem Ergebnis, dass die kein Vergleichstest ist:
           SELECT *
           FROM Printer
           WHERE ptrtype IS NULL AND price < 300;
                
    —siehe IS [NOT] NULL.

Hinweis zu String-Vergleichen

Werden CHAR- und VARCHAR-Felder auf Gleichheit verglichen, werden nachfolgende Leerzeichen in allen Fällen ignoriert.

Andere Vergleichsprädikate

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

BETWEEN

Verfügbar: DSQL, PSQL, ESQL

Syntax: 

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

Das BETWEEN-Prädikat prüft, ob ein Wert innerhalb eines angegebenen Bereichs zweier Werte liegt. (NOT BETWEEN prüft, ob dieser Wert außerhalb der beiden Grenzen liegt.)

Die Operanden des BETWEEN-Prädikates sind zwei Argumente kompatibler Datentypen. Anders als in anderen DBMS ist das BETWEEN-Prädikat nicht symmetrisch— ist der kleinere Wert nicht das erste Argument, wird immer FALSE zurückgegeben. Die Suche ist inkludiert (die Werte beider Argumente werden in die Suche eingebunden). Anders ausgedrückt bedeutet dies, dass das BETWEEN-Prädikat auch anders geschrieben werden kann:

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

Wird BETWEEN in Suchkriterien für DML-Abfragen verwendet, kann der Firebird-Optimizer einen Index auf der Suchspalte nutzen, sofern verfügbar.

Beispiel: 

       SELECT *
       FROM EMPLOYEE
       WHERE HIRE_DATE BETWEEN date '01.01.1992' AND CURRENT_DATE
            
LIKE

Verfügbar: 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 LIKE-Prädikat vergleicht zeichenbasierte Ausdrücke mit dem im zweiten Ausdruck definierten Muster. Groß- und Kleinschreibung bzw. Akzent-Sensitivität für den Vergleich wird durch die zugrunde liegende Collation bestimmt. Eine Collation kann für jeden Operanden angegeben werden, wenn erforderlich.

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 dem '%' oder '_' Symbol im Suchstring vorangestellt werden, um anzuzeigen, dass das Symbol als wörtliches Zeichen 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.

    Ü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. Suche nach Mitarbeitern deren Namen aus 5 Buchstaben bestehen, die mit „Sm“ beginnen und mit „th“ enden. Das Prädikat wird wahr für die 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%'
                    

    Anmerkung

    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. Suche nach Tabellen, die das Unterstrich-Zeichen im Namen besitzen. Das Zeichen „#“ wird als Escape-Zeichen definiert:
           SELECT
             RDB$RELATION_NAME
           FROM RDB$RELATIONS
           WHERE RDB$RELATION_NAME LIKE '%#_%' ESCAPE '#'
                    

Siehe auch: STARTING WITH, CONTAINING, SIMILAR TO

STARTING WITH

Verfügbar: 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: DSQL, PSQL, ESQL

Syntax: 

       <value> [NOT] CONTAINING <value>
            

Das Prädikat CONTAINING sucht innerhalb von Zeichenketten oder zeichenkettenähnlichen Datentypen nach der Buchstabenfolge, die im Argument angegeben wurde. Es kann für alphanumerische (zeichenkettenähnliche) Suchen auf Zahlen und Daten genutzt werden. Eine Suche mit CONTAINING unterscheidet nicht nach Groß- und Kleinschreibung. Wird jedoch eine akzentsensitive Collation verwendet, ist auch die Suche akzentsensitiv.

Wenn CONTAINING als Suchkriterium in DML-Abfragen verwendet wird, kann der Firebird-Optimizer einen Index der Suchspalte nutzen, sofern ein passender existiert.

Beispiele: 

  1. Suche nach Projekten, deren Namen die Zeichenkette „Map“ enhalten:
           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: 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.

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 einer eckigen Klammer beginnt, wird alles, was folgt, von der Klasse ausgeschlossen. Alle anderen Zeichen entsprechen:

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

Wird die eckige Klammer nicht am Anfang der Reihe platziert, enthält die Klasse alles vor dieser, mit Ausnahme der Elemente die nach der Klammer vorkommen:

       '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, direkt von einem weiteren Zeichen oder Klasse gefolgt, gibt an, dass das folgende Element gar nicht oder mehrmals vorkommen darf:

       '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 Plus-Zeichen, direkt von einem weiteren Zeichen oder Klasse gefolgt, gibt an, dass das folgende Element einmalig oder mehrmals vorkommen darf:

       '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
                

Folgt eine Zahl in Klammern auf ein Zeichen oder eine Klasse, muss letzteres genau so oft wie angegeben vorkommen:

       '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
                

Wird eine Zahl von einem Komma gefolgt, bedeutet dies, dass das Element mindestens so oft wie angegeben vorkommen muss:

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

Wenn die Klammern zwei Zahlen enthalten, die mittels Komma getrennt sind, die zweite Zahl nicht kleiner als die erste ist, muss das Element mindestens so oft wie die erste Zahl vorkommen und maximal so oft wie in der zweiten Zahl angegeben:

       '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
                

Sonderzeichen escapen

Soll eine Übereinstimmung auf Sonderzeichen innerhalb eines regulären Ausdrucks geprüft werden, muss dieses Zeichen escaped werden. Es gibt kein Standard-Escape-Zeichen; stattdessen definiert der Benutzer eines, wenn dies benötigt wird:

'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.

IS [NOT] DISTINCT FROM

Verfügbar: 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.

Siehe auch: IS [NOT] NULL

IS [NOT] NULL

Verfügbar: 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;
              

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

Inhaltsverzeichnis

EXISTS
IN
SINGULAR

Diese Gruppe von Prädikaten beinhaltet die, die Unterabfragen nutzen um Werte für alle möglichen Arten von Behauptungen zu prüfen. Existenzprädikate werden so genannt, da sie verschiedene Methoden verwenden, um auf die Exiszenz oder nicht-Existenz von Behauptungen zu prüfen. Die Prädikate geben TRUE zurück, wenn die Existenz oder nicht-Existenz bestätigt wurde, andernfalls FALSE.

EXISTS

Verfügbar: DSQL, PSQL, ESQL

Syntax: 

       [NOT] EXISTS(<select_stmt>)
          

Das Prädikat EXISTS nutzt einen Unterabfrage-Ausdruck als Argument. Es gibt TRUE zurück, wenn die Unterabfrage mindestens einen Datensatz zurückgibt; andernfalls gibt es FALSE zurück.

NOT EXISTS gibt FALSE zurück, wenn die Unterabfrage mindestens eine Datenzeile zurückgibt; es gibt andernfalls TRUE zurück.

Anmerkung

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: 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> …])
          

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.

Hinweis

Wenn es im Bereich des Möglichen liegt, dass NULL innerhalb der Suche für eine nicht-Prüfung vorhanden sein kann, 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: DSQL, PSQL, ESQL

Syntax: 

 
       [NOT] SINGULAR(<select_stmt>)
          

Das SINGULAR-Prädikat verwendet eine Unterabfrage als Argument und gibt True zurück, wenn diese exakt eine Datenzeile zurückgibt; andernfalls wird das Prädikat zu False aufgelöst. Die Unterabfrage kann mehrere Ausgabespalten beinhalten, da die Zeilen ja nicht wirklich ausgegeben werden. Sie werden nur auf (einzigartige) Existenz geprüft. Der Kürze halbe, wird häufig nur 'SELECT *' verwendet. Das Prädikat SINGULAR kann nur zwei Werte zurückgeben: TRUE oder FALSE.

Beispiel:  Finde 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

Inhaltsverzeichnis

ALL
ANY and SOME

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 Unterabfrage-Ausdrücken machen es Quantifizierer-Prädikate möglich einzelne Werte mit den Ergebnissen von Unterabfragen zu vergleichen; sie besitzen die folgende gemeinsame Form:

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

ALL

Verfügbar: 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')
            

Wichtig

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: 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')
            

Zurück: AusdrückeFirebird Documentation IndexNach oben: Allgemeine SprachelementeWeiter: Statements der Data Definition (DDL)
Firebird Documentation IndexFirebird 2.5 SprachreferenzAllgemeine Sprachelemente → Prädikate