Kapitel 12. Funktionen für die Benutzung in `SELECT`- und `WHERE`-Klauseln
Zurück |  | Weiter

## Kapitel 12. Funktionen für die Benutzung in `SELECT`- und `WHERE`-Klauseln

Ausdrücke können an mehreren Stellen in MySQL-Anweisungen verwendet werden, so etwa in den `ORDER BY`- oder `HAVING`-Klauseln von `SELECT`-Anweisungen, in der `WHERE`-Klausel einer `SELECT`-, `DELETE`- oder `UPDATE`-Anweisung oder in `SET`-Anweisungen. Ausdrücke können unter Verwendung von literalen Werten, Spaltenwerten, `NULL`, integrierten Funktionen, gespeicherten Funktionen, benutzerdefinierten Funktionen und Operatoren geschrieben werden. Dieses Kapitel beschreibt die Funktionen und Operatoren, die für das Formulieren von Ausdrücken in MySQL zulässig sind. Hinweise zum Schreiben gespeicherter und benutzerdefinierter Funktionen finden Sie in Kapitel 19, Gespeicherte Prozeduren und Funktionen, und Abschnitt 26.3, „Hinzufügen neuer Funktionen zu MySQL“.

Ein Ausdruck, der `NULL` enthält, erzeugt immer einen `NULL`-Wert, sofern in der Dokumentation zur betreffenden Funktion bzw. zum Operator nichts anderes angegeben ist.

Hinweis: Standardmäßig darf kein Whitespace zwischen einem Funktionsnamen und der ihm folgenden Klammer stehen. Auf diese Weise kann der MySQL-Parser zwischen Funktionsaufrufen und Referenzierungen von Tabellen oder Spalten unterscheiden, die den gleichen Namen wie die Funktion haben. Die Funktionsargumente umgebenden Leerzeichen sind hingegen zulässig.

Sie können den MySQL Server anweisen, Leerzeichen nach Funktionsnamen zu akzeptieren, indem Sie beim Start die Option `--sql-mode=IGNORE_SPACE` angeben. (Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.) Einzelne Clientprogramme können dieses Verhalten anfordern, indem sie die Option `CLIENT_IGNORE_SPACE` für `mysql_real_connect()` angeben. In beiden Fällen werden alle Funktionsnamen zu reservierten Wörtern.

Um Weitschweifigkeiten zu verhindern, stellen die meisten Beispiele in diesem Kapitel die Ausgabe von mysql in gekürzter Form dar. Die folgende Ausgabe zeigt das vollständige Format:

    mysql> SELECT MOD(29,9);
    +-----------+
    | mod(29,9) |
    +-----------+
    |         2 |
    +-----------+
    1 rows in set (0.00 sec)

Stattdessen benutzen wir jedoch folgende Ausgabe:

    mysql> SELECT MOD(29,9);
            -> 2

## 12.1. Operatoren

### 12.1.1. Rangfolge von Operatoren

Die folgende Liste zeigt die Rangordnung der Operatoren in umgekehrter Reihenfolge. Operatoren in der gleichen Zeile haben die gleiche Rangstufe.

    :=
    ||, OR, XOR
    &&, AND
    NOT
    BETWEEN, CASE, WHEN, THEN, ELSE
    =, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
    |
    &
    <<, >>
    -, +
    *, /, DIV, %, MOD
    ^
    - (unary minus), ~ (unary bit inversion)
    !
    BINARY, COLLATE

Hinweis: Wenn der SQL-Modus `HIGH_NOT_PRECEDENCE` aktiviert ist, entspricht die Rangstufe von `NOT` der des Operators `!`. Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

Die Abfolge der Operatoren bestimmt die Auswertungsreihenfolge der Begriffe in einem Ausdruck. Um diese Reihenfolge außer Kraft zu setzen und Begriffe explizit zu gruppieren, verwenden Sie Klammern. Zum Beispiel:

    mysql> SELECT 1+2*3;
            -> 7
    mysql> SELECT (1+2)*3;
            -> 9

### 12.1.2. Typumwandlung bei der Auswertung von Ausdrücken

Wenn ein Operator mit Operanden verschiedener Typen verwendet wird, findet eine Typenkonvertierung statt, um die Operanden kompatibel zu machen. Einige Konvertierungen treten implizit auf. So wandelt MySQL beispielsweise Zahlen nach Bedarf in Strings um und umgekehrt.

    mysql> SELECT 1+'1';
            -> 2
    mysql> SELECT CONCAT(2,' test');
            -> '2 test'

Es ist auch möglich, explizite Konvertierungen durchzuführen. Wenn Sie eine Zahl explizit in einen String umwandeln wollen, verwenden Sie die Funktionen `CAST()` oder `CONCAT()` (wobei `CAST()` vorzuziehen ist):

    mysql> SELECT 38.8, CAST(38.8 AS CHAR);
            -> 38.8, '38.8'
    mysql> SELECT 38.8, CONCAT(38.8);
            -> 38.8, '38.8'

Die folgenden Regeln beschreiben, wie die Konvertierung bei Vergleichsoperationen erfolgt:

- Wenn eines der Argumente (oder beide) `NULL` ist, dann ist das Vergleichsergebnis `NULL`. Eine Ausnahme ist der `NULL`-sichere Gleichheitsoperator `<=>`. Bei `NULL <=> NULL` ist das Ergebnis wahr.

- Wenn beide Argumente in einer Vergleichsoperation Strings sind, werden sie als Strings verglichen.

- Sind beide Argumente Integers, dann werden sie als Integers verglichen.

- Hexadezimalwerte werden als binäre Strings behandelt, wenn sie nicht mit einer Zahl verglichen werden.

- Wenn eines der Argumente eine `TIMESTAMP`- oder `DATETIME`-Spalte und das andere Argument eine Konstante ist, dann wird die Konstante vor Durchführung des Vergleichs in einen Zeitstempel umgewandelt. Dies erhöht die ODBC-Kompatibilität. Beachten Sie jedoch, dass dies nicht bei Argumenten für `IN()` gemacht wird! Um ganz sicher zu sein, sollten Sie bei Vergleichen immer vollständige Strings für Datum und/oder Uhrzeit verwenden.

- In allen anderen Fällen werden die Argumente als Fließkommazahlen (reale Zahlen) verglichen.

Die folgenden Beispiele veranschaulichen die Konvertierung von Strings in Zahlen für Vergleichsoperationen:

    mysql> SELECT 1 > '6x';
            -> 0
    mysql> SELECT 7 > '6x';
            -> 1
    mysql> SELECT 0 > 'x6';
            -> 0
    mysql> SELECT 0 = 'x6';
            -> 1

Beachten Sie, dass, wenn Sie eine String-Spalte mit einer Zahl vergleichen, MySQL keinen Index für die Spalte verwenden kann, um den Wert schnell abzurufen. Ist `str_col` eine indizierte String-Spalte, dann kann der Index nicht verwendet werden, um für die folgende Anweisung eine Suche durchzuführen:

    SELECT * FROM tbl_name WHERE str_col=1;

Dies liegt daran, dass es viele verschiedene Strings gibt, die in den Wert `1` konvertiert werden: `'1'`, `' 1'`, `'1a'`, …

### 12.1.3. Vergleichsoperatoren

Vergleichsoperationen haben einen der Werte `1` (`TRUE`), `0` (`FALSE`) oder `NULL` zum Ergebnis. Diese Operationen funktionieren bei Zahlen und Strings gleichermaßen: Nach Bedarf werden Strings in Zahlen und Zahlen in Strings umgewandelt.

Einige der in diesem Abschnitt beschriebenen Funktionen (z. B. `LEAST()` und `GREATEST()`) geben andere Werte als `1` (`TRUE`), `0` (`FALSE`) oder `NULL` zurück. Der Rückgabewert basiert jedoch auf Vergleichsoperationen, die entsprechend den in Abschnitt 12.1.2, „Typumwandlung bei der Auswertung von Ausdrücken“ beschriebenen Regeln durchgeführt wurden.

Um einen Wert zu Vergleichszwecken in einen beliebigen Typ zu konvertieren, können Sie die Funktion `CAST()` verwenden. String-Werte lassen sich mithilfe von `CONVERT()` in einen anderen Zeichensatz konvertieren. Siehe auch Abschnitt 12.8, „Cast-Funktionen und Operatoren“.

Standardmäßig wird die Groß-/Kleinschreibung bei String-Vergleichen nicht unterschieden. Ferner wird hierbei der aktuelle Zeichensatz verwendet. Die Vorgabe ist `latin1` (cp1252 West European). Dieser Zeichensatz ist auch für Deutsch geeignet.

- `=`

  Gleich:

      mysql> SELECT 1 = 0;
              -> 0
      mysql> SELECT '0' = 0;
              -> 1
      mysql> SELECT '0.0' = 0;
              -> 1
      mysql> SELECT '0.01' = 0;
              -> 0
      mysql> SELECT '.01' = 0.01;
              -> 1

- `<=>`

  `NULL`-sicheres Gleich. Dieser Operator führt ebenso wie `=` eine Vergleichsoperation durch, gibt aber `1` statt `NULL` zurück, wenn beide Operanden `NULL` sind, und `0` statt `NULL`, wenn einer der Operanden `NULL` ist.

      mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
              -> 1, 1, 0
      mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
              -> 1, NULL, NULL

- `<>`, `!=`

  Ungleich:

      mysql> SELECT '.01' <> '0.01';
              -> 1
      mysql> SELECT .01 <> '0.01';
              -> 0
      mysql> SELECT 'zapp' <> 'zappp';
              -> 1

- `<=`

  Kleiner oder gleich:

      mysql> SELECT 0.1 <= 2;
              -> 1

- `<`

  Kleiner als:

      mysql> SELECT 2 < 2;
              -> 0

- `>=`

  Größer oder gleich:

      mysql> SELECT 2 >= 2;
              -> 1

- `>`

  Größer als:

      mysql> SELECT 2 > 2;
              -> 0

- `IS `boolean_value``, `IS NOT `boolean_value``

  Vergleicht einen Wert mit einem booleschen Wert, wobei `boolean_value` `TRUE`, `FALSE` oder `UNKNOWN` sein kann.

      mysql> SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;
              -> 1, 1, 1
      mysql> SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;
              -> 1, 1, 0

- `IS NULL`, `IS NOT NULL`

  Prüft, ob ein Wert `NULL` ist oder nicht.

      mysql> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
              -> 0, 0, 1
      mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
              -> 1, 1, 0

  Zum Zwecke der Kompatibilität mit ODBC-Programmen unterstützt MySQL die folgenden Zusatzfunktionen bei der Verwendung von `IS NULL`:

  - Sie können den Datensatz, der den aktuellen `AUTO_INCREMENT`-Wert enthält, durch Absetzen einer Anweisung der folgenden Form unmittelbar nach Erzeugung des Werts ermitteln:

        SELECT * FROM tbl_name WHERE auto_col IS NULL

    Dieses Verhalten kann mithilfe von `SQL_AUTO_IS_NULL=0` deaktiviert werden. Siehe auch Abschnitt 13.5.3, „`SET`“.

  - Bei `DATE`- und `DATETIME`- Spalten, die als `NOT NULL` deklariert sind, können Sie das Sonderdatum `'0000-00-00'` mithilfe einer Anweisung wie der folgenden ermitteln:

        SELECT * FROM tbl_name WHERE date_column IS NULL

    Dies ist erforderlich, um einige ODBC-Anwendungen zum Laufen zu bringen, weil ODBC den Datumswert `'0000-00-00'` nicht unterstützt.

- ``expr` BETWEEN `min` AND `max``

  Wenn `expr` größer oder gleich `min` und `expr` kleiner oder gleich `max` ist, gibt `BETWEEN` `1` zurück, andernfalls `0`. Dies ist äquivalent zu dem Ausdruck `(`min`<= `expr` AND `expr`<= `max`)`, sofern alle Argumente vom selben Typ sind. Andernfalls findet die Typenkonvertierung entsprechend den in Abschnitt 12.1.2, „Typumwandlung bei der Auswertung von Ausdrücken“, beschriebenen Regeln statt, wird aber auf alle drei Argumente angewendet.

      mysql> SELECT 1 BETWEEN 2 AND 3;
              -> 0
      mysql> SELECT 'b' BETWEEN 'a' AND 'c';
              -> 1
      mysql> SELECT 2 BETWEEN 2 AND '3';
              -> 1
      mysql> SELECT 2 BETWEEN 2 AND 'x-3';
              -> 0

- ``expr` NOT BETWEEN `min` AND `max``

  Dies ist das Gleiche wie `NOT (`expr` BETWEEN `min` AND `max`)`.

- `COALESCE(`value`,...)`

  Gibt den ersten Nicht-`NULL`-Wert in der Liste oder aber `NULL` zurück, sofern keine Nicht-`NULL`-Werte vorhanden sind.

      mysql> SELECT COALESCE(NULL,1);
              -> 1
      mysql> SELECT COALESCE(NULL,NULL,NULL);
              -> NULL

- `GREATEST(`value1`,`value2`,...)`

  Gibt von zwei oder mehr Argumenten das größte (d. h. das mit dem höchsten Wert) zurück. Die Argumente werden nach denselben Regeln wie bei `LEAST()` verglichen.

      mysql> SELECT GREATEST(2,0);
              -> 2
      mysql> SELECT GREATEST(34.0,3.0,5.0,767.0);
              -> 767.0
      mysql> SELECT GREATEST('B','A','C');
              -> 'C'

  `GREATEST()` gibt `NULL` zurück, sofern ein Argument `NULL` ist.

- ``expr` IN (`value`,...)`

  Gibt `1` zurück, wenn `expr` gleich einem der Werte in der `IN`-Liste ist, andernfalls wird `0` zurückgegeben. Wenn alle Werte Konstanten sind, werden sie entsprechend dem Typ von `expr` ausgewertet und sortiert. Nachfolgend erfolgt die Suche nach dem Element unter Verwendung einer binären Suche. Das heißt auch, dass `IN` sehr schnell ist, wenn die `IN`-Werteliste ausschließlich aus Konstanten besteht. Andernfalls findet die Typenkonvertierung entsprechend den in Abschnitt 12.1.2, „Typumwandlung bei der Auswertung von Ausdrücken“, beschriebenen Regeln statt, wird aber auf alle Argumente angewendet.

      mysql> SELECT 2 IN (0,3,5,'wefwf');
              -> 0
      mysql> SELECT 'wefwf' IN (0,3,5,'wefwf');
              -> 1

  Die Anzahl der Werte in der `IN`-Liste wird nur durch den Wert von `max_allowed_packet` beschränkt.

  Um mit dem SQL-Standard konform zu gehen, gibt `IN` `NULL` nicht nur dann zurück, wenn der Ausdruck auf der linken Seite `NULL` ist, sondern auch dann, wenn keine Übereinstimmung in der Liste gefunden wird und einer der Ausdrücke in der Liste `NULL` ist.

  Die `IN()`-Syntax kann auch zum Schreiben verschiedener Arten von Unterabfragen verwendet werden. Siehe auch Abschnitt 13.2.8.3, „Unterabfragen mit `ANY`, `IN` und `SOME`“.

- ``expr` NOT IN (`value`,...)`

  Dies ist das Gleiche wie `NOT (`expr` IN (`value`,...))`.

- `ISNULL(`expr`)`

  Wenn `expr` `NULL` ist, gibt `ISNULL()` `1` zurück, andernfalls `0`.

      mysql> SELECT ISNULL(1+1);
              -> 0
      mysql> SELECT ISNULL(1/0);
              -> 1

  `ISNULL()` kann anstelle von `=` verwendet werden, um zu überprüfen, ob ein Wert `NULL` ist. (Der Vergleich eines Werts mit `NULL` unter Verwendung von `=` gibt immer `FALSE` aus.)

  Die Funktion `ISNULL()` weist einige spezielle Eigenschaften des Vergleichsoperators `IS NULL` auf. Siehe auch die Beschreibung zu `IS NULL`.

- `INTERVAL(`N`,`N1`,`N2`,`N3`,...)`

  Gibt `0` zurück, wenn `N` < `N1` ist, `1`, wenn `N` < `N2` usw., oder `-1`, wenn `N` `NULL` ist. Alle Argumente werden als Integers behandelt. Es ist erforderlich, dass `N1` < `N2` < `N3` < `...` < `Nn` ist, damit diese Funktion einwandfrei arbeitet. Das liegt daran, dass eine binäre (und damit sehr schnelle) Suche verwendet wird.

      mysql> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
              -> 3
      mysql> SELECT INTERVAL(10, 1, 10, 100, 1000);
              -> 2
      mysql> SELECT INTERVAL(22, 23, 30, 44, 200);
              -> 0

- `LEAST(`value1`,`value2`,...)`

  Gibt von zwei oder mehr Argumenten das kleinste (d. h. das mit dem niedrigsten Wert) zurück. Die Argumente werden unter Anwendung der folgenden Regeln verglichen:

  - Wenn der Rückgabewert in einem `INTEGER`-Kontext verwendet wird oder alle Argumente Integer-Werte sind, dann werden sie als Integers verglichen.

  - Wenn der Rückgabewert in einem `REAL`-Kontext verwendet wird oder alle Argumente reale Zahlen sind, dann werden sie als reale Zahlen verglichen.

  - Ist ein Argument ein String mit Unterscheidung der Groß-/Kleinschreibung, dann werden die Argumente als Strings mit Unterscheidung der Groß-/Kleinschreibung verglichen.

  - In allen anderen Fällen werden die Argumente als Strings ohne Unterscheidung der Groß-/Kleinschreibung verglichen.

  `LEAST()` gibt `NULL` zurück, sofern ein Argument `NULL` ist.

      mysql> SELECT LEAST(2,0);
              -> 0
      mysql> SELECT LEAST(34.0,3.0,5.0,767.0);
              -> 3.0
      mysql> SELECT LEAST('B','A','C');
              -> 'A'

  Beachten Sie, dass die oben beschriebenen Konvertierungsregeln in einigen Grenzfällen fragwürdige Ergebnisse erzeugen können:

      mysql> SELECT CAST(LEAST(3600, 9223372036854775808.0) as SIGNED);
              -> -9223372036854775808

  Dies passiert, weil MySQL `9223372036854775808.0` in einem Integer-Kontext liest. Das Integer-Format ist aber nicht geeignet, den Wert darzustellen, d. h., er wird in einen vorzeichenbehafteten Integer umgewandelt.

### 12.1.4. Logische Operatoren

In SLQ werden alle logischen Operatoren als `TRUE`, `FALSE` oder `NULL` (`UNKNOWN`) ausgewertet. In MySQL ist dies als 1 (`TRUE`), 0 (`FALSE`) und `NULL` implementiert. Dies ist größtenteils auf den verschiedenen SQL-Datenbankservern identisch, auch wenn einige Server einen beliebigen Nichtnullwert für `TRUE` zurückgeben.

- `NOT`, `!`

  Logisches NOT (NICHT). Wird zu `1`, wenn der Operand `0` ist, und zu `0`, wenn der Operand nicht null ist. `NOT NULL` gibt `NULL` zurück.

      mysql> SELECT NOT 10;
              -> 0
      mysql> SELECT NOT 0;
              -> 1
      mysql> SELECT NOT NULL;
              -> NULL
      mysql> SELECT ! (1+1);
              -> 0
      mysql> SELECT ! 1+1;
              -> 1

  Das letzte Beispiel erzeugt `1`, weil der Ausdruck auf die gleiche Weise ausgewertet wird wie `(!1)+1`.

- `AND`, `&&`

  Logisches AND (UND). Gibt `1` zurück, wenn alle Operanden weder null noch `NULL` sind; wenn ein oder mehr Operanden `0` sind, wird `0` zurückgegeben, andernfalls `NULL`.

      mysql> SELECT 1 && 1;
              -> 1
      mysql> SELECT 1 && 0;
              -> 0
      mysql> SELECT 1 && NULL;
              -> NULL
      mysql> SELECT 0 && NULL;
              -> 0
      mysql> SELECT NULL && 0;
              -> 0

- `OR`, `||`

  Logisches OR (ODER). Wenn beide Operanten nicht `NULL` sind, ist das Ergebnis `1`, sofern ein beliebiger Operand nicht null ist, andernfalls `0`. Bei einem `NULL`-Operanden ist das Ergebnis `1`, wenn der andere Operand nicht null ist, andernfalls ist es `NULL`. Sind beide Operanden `NULL`, dann ist das Ergebnis `NULL`.

      mysql> SELECT 1 || 1;
              -> 1
      mysql> SELECT 1 || 0;
              -> 1
      mysql> SELECT 0 || 0;
              -> 0
      mysql> SELECT 0 || NULL;
              -> NULL
      mysql> SELECT 1 || NULL;
              -> 1

- `XOR`

  Logisches XOR (exklusives ODER). Gibt `NULL` zurück, wenn ein Operand `NULL` ist. Bei Nicht-`NULL`-Operanden wird `1` zurückgegeben, wenn eine ungerade Anzahl von Operanden nicht null ist, andernfalls wird `0` zurückgegeben.

      mysql> SELECT 1 XOR 1;
              -> 0
      mysql> SELECT 1 XOR 0;
              -> 1
      mysql> SELECT 1 XOR NULL;
              -> NULL
      mysql> SELECT 1 XOR 1 XOR 1;
              -> 1

  `a XOR b` ist mathematisch identisch mit `(a AND (NOT b)) OR ((NOT a) and b)`.

## 12.2. Ablaufsteuerungsfunktionen

- `CASE `value` WHEN [`compare_value`] THEN `result` [WHEN [`compare_value`] THEN `result` ...] [ELSE `result`] END`

  `CASE WHEN [`condition`] THEN `result` [WHEN [`condition`] THEN `result` ...] [ELSE `result`] END`

  Die erste Version gibt `result` zurück, wobei gilt: ``value`=`compare_value``. Die zweite Version gibt das Ergebnis der ersten Bedingung zurück, die wahr ist. Wenn kein passender Ergebniswert existiert, wird das Ergebnis nach `ELSE` oder aber `NULL` (sofern kein `ELSE`-Teil vorhanden ist) zurückgegeben.

      mysql> SELECT CASE 1 WHEN 1 THEN 'one'
          ->     WHEN 2 THEN 'two' ELSE 'more' END;
              -> 'one'
      mysql> SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
              -> 'true'
      mysql> SELECT CASE BINARY 'B'
          ->     WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
              -> NULL

  Der vorgabeseitige Rückgabetyp eines `CASE`-Ausdrucks ist der kompatible zusammengefasste Typ aller Rückgabewerte, hängt aber auch vom Kontext ab, in dem er verwendet wird. Bei Verwendung in einem String-Kontext wird das Ergebnis als String zurückgegeben. Bei Verwendung in einem numerischen Kontext wird das Ergebnis als Dezimalwert, reale Zahl oder Integer-Wert zurückgegeben.

  Hinweis: Die hier gezeigte Syntax des `CASE`-Ausdrucks unterscheidet sich ein wenig von der SQL-Syntax der `CASE`-Anweisung, wie sie in Abschnitt 19.2.10.2, „`CASE`-Anweisung“, zur Verwendung in gespeicherten Routinen beschrieben wird. Die `CASE`-Anweisung kann keine `ELSE NULL`-Klausel haben und wird mit `END CASE` anstelle von `END` abgeschlossen.

- `IF(`expr1`,`expr2`,`expr3`)`

  Wenn `expr1` `TRUE` ist (``expr1`<> 0` und ``expr1` <> NULL`), dann gibt `IF()` `expr2` zurück; andernfalls gibt es `expr3` zurück. `IF()` gibt je nach Verwendungskontext einen numerischen oder einen String-Wert zurück.

      mysql> SELECT IF(1>2,2,3);
              -> 3
      mysql> SELECT IF(1<2,'yes','no');
              -> 'yes'
      mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
              -> 'no'

  Ist nur einer der Ausdrücke `expr2` oder `expr3` explizit `NULL`, dann ist der Ergebnistyp der `IF()`-Funktion der Typ des Nicht-`NULL`-Ausdrucks.

  `expr1` wird als Integer-Wert ausgewertet, d. h., wenn Sie Fließkomma- oder String-Werte prüfen, sollten Sie dies mit einer Vergleichsoperation tun.

      mysql> SELECT IF(0.1,1,0);
              -> 0
      mysql> SELECT IF(0.1<>0,1,0);
              -> 1

  Im ersten gezeigten Fall gibt `IF(0.1)` `0` zurück, weil `0.1` in einen Integer-Wert konvertiert wird, was zur Prüfung von `IF(0)` führt. Dies ist unter Umständen nicht das, was Sie erwarten. Im zweiten Fall prüft der Vergleich den ursprünglichen Fließkommawert, um festzustellen, ob dieser nicht null ist. Das Ergebnis des Vergleichs wird als Integer verwendet.

  Der Standardrückgabetyp von `IF()` (der wichtig sein kann, wenn er in einer Temporärtabelle gespeichert wird) wird wie folgt berechnet:

  Ausdruck | Rückgabewert
  `expr2` oder `expr3` gibt einen String zurück | String
  `expr2` oder `expr3` gibt einen Fließkommawert zurück | Fließkommazahl
  `expr2` oder `expr3` gibt einen Integer zurück | Integer

  Wenn sowohl `expr2` als auch `expr3` Strings sind, wird beim Ergebnis die Groß-/Kleinschreibung unterschieden, sofern dies bei einem der Strings ebenfalls der Fall ist.

  Hinweis: Es gibt auch eine `IF`-Anweisung, die sich von der hier beschriebenen `IF()`-Funktion unterscheidet. Siehe auch Abschnitt 19.2.10.1, „`IF`-Anweisung“.

- `IFNULL(`expr1`,`expr2`)`

  Wenn `expr1` nicht `NULL` ist, gibt `IFNULL()` `expr1` zurück; andernfalls wird `expr2` zurückgegeben. `IFNULL()` gibt je nach Verwendungskontext einen numerischen oder einen String-Wert zurück.

      mysql> SELECT IFNULL(1,0);
              -> 1
      mysql> SELECT IFNULL(NULL,10);
              -> 10
      mysql> SELECT IFNULL(1/0,10);
              -> 10
      mysql> SELECT IFNULL(1/0,'yes');
              -> 'yes'

  Der Standardergebniswert von `IFNULL(`expr1`,`expr2`)` ist der „allgemeinere“ der beiden Ausdrücke in der Reihenfolge `STRING`, `REAL` oder `INTEGER`. Betrachten Sie den Fall einer auf Ausdrücken basierenden Tabelle oder einen Fall, in dem MySQL einen von `IFNULL()` zurückgegebenen Wert intern in einer Temporärtabelle speichern muss:

      mysql> CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;
      mysql> DESCRIBE tmp;
      +-------+---------+------+-----+---------+-------+
      | Field | Type    | Null | Key | Default | Extra |
      +-------+---------+------+-----+---------+-------+
      | test  | char(4) |      |     |         |       |
      +-------+---------+------+-----+---------+-------+

  In diesem Beispiel ist der Typ der Spalte `test` `CHAR(4)`.

- `NULLIF(`expr1`,`expr2`)`

  Gibt `NULL` zurück, wenn ``expr1` = `expr2`` wahr ist; andernfalls wird `expr1` zurückgegeben. Dies ist das Gleiche wie `CASE WHEN `expr1` = `expr2` THEN NULL ELSE `expr1` END`.

      mysql> SELECT NULLIF(1,1);
              -> NULL
      mysql> SELECT NULLIF(1,2);
              -> 1

  Beachten Sie, dass MySQL `expr1` zweimal auswertet, wenn die Argumente nicht gleich sind.

## 12.3. String-Funktionen

String-Funktionen geben `NULL` zurück, wenn die Länge des Ergebnisses größer wäre als der Wert der Systemvariablen `max_allowed_packet`. Siehe auch Abschnitt 7.5.2, „Serverparameter feineinstellen“.

Bei Funktionen, die mit String-Positionen operieren, hat die erste Position die Nummer 1.

- `ASCII(`str`)`

  Gibt den numerischen Wert des Zeichens ganz links im String `str` zurück. Gibt `0` zurück, wenn `str` der Leer-String ist. Gibt `NULL` zurück, wenn `str` `NULL` ist. `ASCII()` funktioniert bei Zeichen mit numerischen Werten zwischen `0` und `255`.

      mysql> SELECT ASCII('2');
              -> 50
      mysql> SELECT ASCII(2);
              -> 50
      mysql> SELECT ASCII('dx');
              -> 100

  Siehe auch die Funktion `ORD()`.

- `BIN(`N`)`

  Gibt eine String-Darstellung des Binärwerts `N` zurück, wobei `N` eine `BIGINT`-Zahl ist. Dies ist äquivalent mit `CONV(`N`,10,2)`. Gibt `NULL` zurück, wenn `N` `NULL` ist.

      mysql> SELECT BIN(12);
              -> '1100'

- `BIT_LENGTH(`str`)`

  Gibt die Länge des Strings `str` angegeben in Bit zurück.

      mysql> SELECT BIT_LENGTH('text');
              -> 32

- `CHAR(`N`,... [USING `charset_name`])`

  `CHAR()` interpretiert jedes Argument `N` als Integer und gibt einen String zurück, der aus den Zeichen besteht, die durch die Codewerte dieser Integers beschrieben werden. `NULL`-Werte werden übersprungen.

      mysql> SELECT CHAR(77,121,83,81,'76');
              -> 'MySQL'
      mysql> SELECT CHAR(77,77.3,'77.3');
              -> 'MMM'

  `CHAR()`-Argumente, die größer als 255 sind, werden in mehrere Ergebnisbytes konvertiert. So ist beispielsweise `CHAR(256)` äquivalent zu `CHAR(1,0)`, und `CHAR(256*256)` ist äquivalent zu `CHAR(1,0,0)`:

      mysql> SELECT HEX(CHAR(1,0)), HEX(CHAR(256));
      +----------------+----------------+
      | HEX(CHAR(1,0)) | HEX(CHAR(256)) |
      +----------------+----------------+
      | 0100           | 0100           |
      +----------------+----------------+
      mysql> SELECT HEX(CHAR(1,0,0)), HEX(CHAR(256*256));
      +------------------+--------------------+
      | HEX(CHAR(1,0,0)) | HEX(CHAR(256*256)) |
      +------------------+--------------------+
      | 010000           | 010000             |
      +------------------+--------------------+

  Standardmäßig gibt `CHAR()` einen Binär-String zurück. Um einen String in einem gegebenen Zeichensatz zu erzeugen, verwenden Sie die optionale Klausel `USING`:

      mysql> SELECT CHARSET(CHAR(0x65)), CHARSET(CHAR(0x65 USING utf8));
      +---------------------+--------------------------------+
      | CHARSET(CHAR(0x65)) | CHARSET(CHAR(0x65 USING utf8)) |
      +---------------------+--------------------------------+
      | binary              | utf8                           |
      +---------------------+--------------------------------+

  Wenn `USING` angegeben wird und der Ergebnis-String für den angegebenen Zeichensatz unzulässig ist, wird eine Warnung ausgegeben. Ferner wird, wenn der strikte SQL-Modus aktiviert ist, das Ergebnis von `CHAR()` zu `NULL`.

- `CHAR_LENGTH(`str`)`

  Gibt die Länge des Strings `str` angegeben in Zeichen zurück. Ein Multibytezeichen wird als ein Zeichen gezählt. Das bedeutet, dass `LENGTH()` für einen aus fünf Zweibytezeichen bestehenden String `10` zurückgibt, `CHAR_LENGTH()` hingegen `5`.

- `CHARACTER_LENGTH(`str`)`

  `CHARACTER_LENGTH()` ist ein Synonym für `CHAR_LENGTH()`.

- `CONCAT(`str1`,`str2`,...)`

  Gibt den String zurück, der aus der Verkettung der Argumente entsteht. Kann ein oder mehrere Argumente haben. Sind alle Argumente nichtbinäre Strings, dann ist das Ergebnis ein nichtbinärer String. Enthalten die Argumente Binär-Strings, dann ist das Ergebnis ein Binär-String. Ein numerisches Argument wird in seinen äquivalenten Binär-String konvertiert. Wollen Sie dies vermeiden, dann können Sie wie im folgenden Beispiel eine explizite Typenumwandlung vornehmen:

      SELECT CONCAT(CAST(int_col AS CHAR), char_col);

  `CONCAT()` gibt `NULL` zurück, sofern ein Argument `NULL` ist.

      mysql> SELECT CONCAT('My', 'S', 'QL');
              -> 'MySQL'
      mysql> SELECT CONCAT('My', NULL, 'QL');
              -> NULL
      mysql> SELECT CONCAT(14.3);
              -> '14.3'

- `CONCAT_WS(`separator`,`str1`,`str2`,...)`

  `CONCAT_WS()` (Concatenate With Separator) ist eine Sonderform von `CONCAT()`. Das erste Argument ist das Trennzeichen für die verbleibenden Argumente. Das Trennzeichen wird zwischen die zu verkettenden Strings gesetzt. Das Trennzeichen kann ein String wie auch die übrigen Argumente sein. Wenn das Trennzeichen `NULL` ist, ist das Ergebnis ebenfalls `NULL`.

      mysql> SELECT CONCAT_WS(',','First name','Second name','Last Name');
              -> 'First name,Second name,Last Name'
      mysql> SELECT CONCAT_WS(',','First name',NULL,'Last Name');
              -> 'First name,Last Name'

  `CONCAT_WS()` überspringt Leer-Strings nicht. `NULL`-Werte nach dem Trennzeichenargument werden hingegen übersprungen.

- `CONV(`N`,`from_base`,`to_base`)`

  Wandelt Zahlen zwischen verschiedenen Zahlenbasen um. Gibt eine String-Darstellung der Zahl `N` zurück, die von der Basis `from_base` in die Basis `to_base` konvertiert wurde. Gibt `NULL` zurück, wenn eines der Argumente `NULL` ist. Das Argument `N` wird als Integer interpretiert, kann aber als Integer oder als String angegeben werden. Die kleinste Basis ist `2`, die größte `36`. Wenn `to_base` eine negative Zahl ist, wird `N` als vorzeichenbehaftete Zahl betrachtet. Andernfalls wird `N` als vorzeichenlos behandelt. `CONV()` arbeitet mit einer Genauigkeit von 64 Bit.

      mysql> SELECT CONV('a',16,2);
              -> '1010'
      mysql> SELECT CONV('6E',18,8);
              -> '172'
      mysql> SELECT CONV(-17,10,-18);
              -> '-H'
      mysql> SELECT CONV(10+'10'+'10'+0xa,10,10);
              -> '40'

- `ELT(`N`,`str1`,`str2`,`str3`,...)`

  Gibt `str1` zurück, wenn `N` = `1` ist, `str2`, wenn `N` = `2` usw. Gibt `NULL` zurück, wenn `N` kleiner als `1` oder größer als die Anzahl der Argumente ist. `ELT()` ist die Ergänzung zu `FIELD()`.

      mysql> SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');
              -> 'ej'
      mysql> SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');
              -> 'foo'

- `EXPORT_SET(`bits`,`on`,`off`[,`separator`[,`number_of_bits`]])`

  Gibt einen String zurück. Dabei erhalten Sie für jedes im Wert `bits` gesetzte Bit den String `on` und für jedes nicht gesetzte Bit den String `off`. Bits in `bits` werden von rechts nach links (d. h. von den niederwertigen zu den höherwertigen Bits) untersucht. Strings werden dem Ergebnis hingegen von links nach rechts hinzugefügt. Sie sind durch einen Trenn-String voneinander getrennt (standardmäßig ist dies das Kommazeichen ‘`,`’). Die Anzahl der zu untersuchenden Bits wird über `number_of_bits` angegeben (Standard: 64).

      mysql> SELECT EXPORT_SET(5,'Y','N',',',4);
              -> 'Y,N,Y,N'
      mysql> SELECT EXPORT_SET(6,'1','0',',',10);
              -> '0,1,1,0,0,0,0,0,0,0'

- `FIELD(`str`,`str1`,`str2`,`str3`,...)`

  Gibt den Index (d. h. die Position) von `str` in der Liste `str1`, `str2`, `str3`, `...` zurück. Gibt `0` zurück, wenn `str` nicht gefunden wird.

  Sind alle Argumente für `FIELD()` Strings, dann werden alle Argumente als Strings verglichen. Sind alle Argumente Zahlen, dann werden sie als Zahlen verglichen. Andernfalls werden die Argumente als Fließkommazahlen verglichen.

  Wenn `str` `NULL` ist, ist der Rückgabewert `0`, weil ein Vergleich von `NULL` mit einem beliebigen Wert fehlschlägt. `FIELD()` ist die Ergänzung zu `ELT()`.

      mysql> SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
              -> 2
      mysql> SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
              -> 0

- `FIND_IN_SET(`str`,`strlist`)`

  Gibt einen Wert im Bereich zwischen 1 und `N` zurück, wenn der String `str` Bestandteil der String-Liste `strlist` ist, die aus `N` Teil-Strings besteht. Eine String-Liste ist ein String, der aus durch Kommata getrennten Teil-Strings besteht. Wenn das erste Argument ein konstanter String und das zweite eine Spalte des Typs `SET` ist, wird die Funktion `FIND_IN_SET()` so optimiert, dass sie eine Bitarithmetik verwendet. Gibt `0` zurück, wenn `str` nicht in `strlist` enthalten oder `strlist` der Leer-String ist. Gibt `NULL` zurück, wenn eines der Argumente `NULL` ist. Diese Funktion arbeitet nicht einwandfrei, wenn das erste Argument ein Komma (‘`,`’) enthält.

      mysql> SELECT FIND_IN_SET('b','a,b,c,d');
              -> 2

- `FORMAT(`X`,`D`)`

  Formatiert die Zahl `X` in ein Format wie `'#,###,###.##'`, gerundet auf `D` Dezimalstellen, und gibt das Ergebnis als String zurück. Wenn `D` `0` ist, hat das Ergebnis keinen Dezimalpunkt und keine Nachkommastellen.

      mysql> SELECT FORMAT(12332.123456, 4);
              -> '12,332.1235'
      mysql> SELECT FORMAT(12332.1,4);
              -> '12,332.1000'
      mysql> SELECT FORMAT(12332.2,0);
              -> '12,332'

- `HEX(`N_or_S`)`

  Wenn `N_or_S` eine Zahl ist, wird eine String-Darstellung des Hexadezimalwerts von `N` zurückgegeben, wobei `N` eine Longlong-Zahl (`BIGINT`) ist. Dies ist äquivalent mit `CONV(N,10,16)`.

  Wenn `N_or_S` ein String ist, wird eine hexadezimale String-Darstellung von `N_or_S` zurückgegeben, wobei jedes Zeichen in `N_or_S` in zwei Hexadezimalstellen konvertiert wird.

      mysql> SELECT HEX(255);
              -> 'FF'
      mysql> SELECT 0x616263;
              -> 'abc'
      mysql> SELECT HEX('abc');
              -> 616263

- `INSERT(`str`,`pos`,`len`,`newstr`)`

  Gibt den String `str` zurück. Hierbei wird der an der Position `pos` beginnende und `len` Zeichen lange Teil-String durch den String `newstr` ersetzt. Gibt den Ursprungs-String zurück, wenn `pos` größer als die Gesamtlänge des Strings ist. Ersetzt wird der Rest des an der Position `pos` beginnenden Strings, wenn `len` größer ist als der verbleibende String. Gibt `NULL` zurück, wenn eines der Argumente `NULL` ist.

      mysql> SELECT INSERT('Quadratic', 3, 4, 'What');
              -> 'QuWhattic'
      mysql> SELECT INSERT('Quadratic', -1, 4, 'What');
              -> 'Quadratic'
      mysql> SELECT INSERT('Quadratic', 3, 100, 'What');
              -> 'QuWhat'

  Diese Funktion ist multibytesicher.

- `INSTR(`str`,`substr`)`

  Gibt die Position des ersten Auftretens des Teil-Strings `substr` im String `str` zurück. Dies ist weitgehend identisch mit der mit zwei Argumenten arbeitenden Form von `LOCATE()`; der einzige Unterschied besteht darin, dass die Reihenfolge der Argumente umgekehrt ist.

      mysql> SELECT INSTR('foobarbar', 'bar');
              -> 4
      mysql> SELECT INSTR('xbar', 'foobar');
              -> 0

  Diese Funktion ist multibytesicher. Die Groß-/Kleinschreibung wird nur dann unterschieden, wenn mindestens ein Argument ein Binär-String ist.

- `LCASE(`str`)`

  `LCASE()` ist ein Synonym für `LOWER()`.

- `LEFT(`str`,`len`)`

  Gibt beginnend von links die durch `len` angegebene Anzahl von Zeichen des Strings `str` zurück.

      mysql> SELECT LEFT('foobarbar', 5);
              -> 'fooba'

- `LENGTH(`str`)`

  Gibt die Länge des Strings `str` angegeben in Byte zurück. Ein Multibytezeichen wird als mehrere Bytes gezählt. Das bedeutet, dass `LENGTH()` für einen aus fünf Zweibytezeichen bestehenden String `10` zurückgibt, `CHAR_LENGTH()` hingegen `5`.

      mysql> SELECT LENGTH('text');
              -> 4

- `LOAD_FILE(`file_name`)`

  Liest die Datei und gibt den Dateiinhalt als String zurück. Damit diese Funktion verwendet werden kann, muss die Datei auf dem Serverhost liegen. Sie benötigen die Berechtigung `FILE` und müssen den vollständigen Pfadnamen der Datei angeben. Die Datei muss von allen lesbar und ihre Größe geringer als `max_allowed_packet` Bytes sein.

  Wenn die Datei nicht vorhanden ist oder nicht gelesen werden kann, weil eine der vorherigen Bedingungen nicht erfüllt ist, gibt die Funktion `NULL` zurück.

      mysql> UPDATE t
                  SET blob_col=LOAD_FILE('/tmp/picture')
                  WHERE id=1;

- `LOCATE(`substr`,`str`)`, `LOCATE(`substr`,`str`,`pos`)`

  Die erste Syntax gibt die Position des ersten Auftretens des Teil-Strings `substr` im String `str` zurück. Die zweite Syntax gibt die Position des ersten Auftretens des Teil-Strings `substr` im String `str` beginnend bei der Position `pos` zurück. Gibt `0` zurück, wenn `substr` nicht in `str` enthalten ist.

      mysql> SELECT LOCATE('bar', 'foobarbar');
              -> 4
      mysql> SELECT LOCATE('xbar', 'foobar');
              -> 0
      mysql> SELECT LOCATE('bar', 'foobarbar', 5);
              -> 7

  Diese Funktion ist multibytesicher. Die Groß-/Kleinschreibung wird nur dann unterschieden, wenn mindestens ein Argument ein Binär-String ist.

- `LOWER(`str`)`

  Gibt den String `str` mit allen Zeichen zurück, die aufgrund der aktuellen Zeichensatzzuordnung in Kleinbuchstaben umgewandelt wurden. Der Standardzeichensatz ist `latin1` (cp1252 West European).

      mysql> SELECT LOWER('QUADRATICALLY');
              -> 'quadratically'

  Diese Funktion ist multibytesicher.

- `LPAD(`str`,`len`,`padstr`)`

  Gibt den String `str` zurück. Dieser wurde nach links mit dem String `padstr` auf eine Länge von `len` Zeichen aufgefüllt. Wenn `str` länger als `len` ist, wird der Rückgabewert auf `len` Zeichen gekürzt.

      mysql> SELECT LPAD('hi',4,'??');
              -> '??hi'
      mysql> SELECT LPAD('hi',1,'??');
              -> 'h'

- `LTRIM(`str`)`

  Gibt den String `str` zurück, bei dem alle Leerzeichen am Anfang entfernt wurden.

      mysql> SELECT LTRIM('  barbar');
              -> 'barbar'

  Diese Funktion ist multibytesicher.

- `MAKE_SET(`bits`,`str1`,`str2`,...)`

  Gibt einen Mengenwert (d. h. einen String, der aus mit Kommata getrennten Teil-Strings besteht) zurück. Dieser besteht aus den Strings, bei denen das entsprechende Bit in `bits` gesetzt ist. `str1` entspricht Bit 0, `str2` Bit 1 usw. `NULL`-Werte in `str1`, `str2`, `...` werden nicht an das Ergebnis angehängt.

      mysql> SELECT MAKE_SET(1,'a','b','c');
              -> 'a'
      mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
              -> 'hello,world'
      mysql> SELECT MAKE_SET(1 | 4,'hello','nice',NULL,'world');
              -> 'hello'
      mysql> SELECT MAKE_SET(0,'a','b','c');
              -> ''

- `MID(`str`,`pos`,`len`)`

  `MID(`str`,`pos`,`len`)` ist ein Synonym für `SUBSTRING(`str`,`pos`,`len`)`.

- `OCT(`N`)`

  Gibt eine String-Darstellung des Oktalwerts `N` zurück, wobei `N` eine `BIGINT`-Zahl ist. Dies ist äquivalent mit `CONV(`N`,10,8)`. Gibt `NULL` zurück, wenn `N` `NULL` ist.

      mysql> SELECT OCT(12);
              -> '14'

- `OCTET_LENGTH(`str`)`

  `OCTET_LENGTH()` ist ein Synonym für `LENGTH()`.

- `ORD(`str`)`

  Wenn das Zeichen ganz links im String `str` ein Multibytezeichen ist, wird der Code dieses Zeichens zurückgegeben. Dieser wird aus den numerischen Werten der Bytes gebildet, aus denen das Zeichen besteht. Hierbei kommt folgende Formel zum Einsatz:

        (1st byte code)
      + (2nd byte code × 256)
      + (3rd byte code × 2562) ...

  Wenn das Zeichen ganz links im String kein Multibytezeichen ist, gibt `ORD()` denselben Wert zurück wie die Funktion `ASCII()`.

      mysql> SELECT ORD('2');
              -> 50

- `POSITION(`substr` IN `str`)`

  `POSITION(`substr` IN `str`)` ist ein Synonym für `LOCATE(`substr`,`str`)`.

- `QUOTE(`str`)`

  Setzt einen String in Anführungszeichen, um ein Ergebnis zu erzeugen, das als angemessen gekennzeichneter Datenwert in einer SQL-Anweisung verwendet werden kann. Der String wird in einfache Anführungszeichen gesetzt zurückgegeben. Jedem enthaltenen einzelnen Anführungszeichen (‘`'`’), Backslash (‘`\`’), ASCII-`NUL` und Strg+Z wird ein Backslash vorangestellt. Wenn das Argument `NULL` ist, ist der Rückgabewert das Wort „NULL“ ohne Anführungszeichen.

      mysql> SELECT QUOTE('Don\'t!');
              -> 'Don\'t!'
      mysql> SELECT QUOTE(NULL);
              -> NULL

- `REPEAT(`str`,`count`)`

  Gibt einen String zurück, der aus dem String `str` besteht, welcher `count` Mal wiederholt wird. Wenn `count` kleiner als 1 ist, wird ein leerer String zurückgegeben. Gibt `NULL` zurück, wenn `str` oder `count` `NULL` sind.

      mysql> SELECT REPEAT('MySQL', 3);
              -> 'MySQLMySQLMySQL'

- `REPLACE(`str`,`from_str`,`to_str`)`

  Gibt den String `str` zurück, bei dem jedes Auftreten des Strings `from_str` durch den String `to_str` ersetzt wurde. `REPLACE()` führt bei der Suche nach `from_str` einen Vergleich unter Berücksichtigung der Groß-/Kleinschreibung durch.

      mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
              -> 'WwWwWw.mysql.com'

  Diese Funktion ist multibytesicher.

- `REVERSE(`str`)`

  Gibt den String `str` zurück, bei dem die Reihenfolge der Zeichen umgekehrt wurde.

      mysql> SELECT REVERSE('abc');
              -> 'cba'

  Diese Funktion ist multibytesicher.

- `RIGHT(`str`,`len`)`

  Gibt beginnend von rechts die durch `len` angegebene Anzahl von Zeichen des Strings `str` zurück.

      mysql> SELECT RIGHT('foobarbar', 4);
              -> 'rbar'

  Diese Funktion ist multibytesicher.

- `RPAD(`str`,`len`,`padstr`)`

  Gibt den String `str` zurück. Dieser wurde nach rechts mit dem String `padstr` auf eine Länge von `len` Zeichen aufgefüllt. Wenn `str` länger als `len` ist, wird der Rückgabewert auf `len` Zeichen gekürzt.

      mysql> SELECT RPAD('hi',5,'?');
              -> 'hi???'
      mysql> SELECT RPAD('hi',1,'?');
              -> 'h'

  Diese Funktion ist multibytesicher.

- `RTRIM(`str`)`

  Gibt den String `str` zurück, bei dem alle Leerzeichen am Ende entfernt wurden.

      mysql> SELECT RTRIM('barbar   ');
              -> 'barbar'

  Diese Funktion ist multibytesicher.

- `SOUNDEX(`str`)`

  Gibt einen Soundex-String aus `str` zurück. Zwei Strings, die fast identisch klingen, sollten identische Soundex-Strings haben. Ein Soundex-String ist standardmäßig vier Zeichen lang, die Funktion `SOUNDEX()` gibt aber einen beliebig langen String zurück. Sie können `SUBSTRING()` für das Ergebnis verwenden, um einen Standard-Soundex-String zu erhalten. Alle nicht alphabetischen Zeichen in `str` werden ignoriert. Alle internationalen alphabetischen Zeichen außerhalb des Bereichs A bis Z werden als Vokale behandelt.

      mysql> SELECT SOUNDEX('Hello');
              -> 'H400'
      mysql> SELECT SOUNDEX('Quadratically');
              -> 'Q36324'

  Hinweis: Diese Funktion implementiert den Soundex-Originalalgorithmus und nicht die gängigere erweiterte Version, wie sie auch von D. Knuth beschrieben wird. Der Unterschied besteht darin, dass die Originalversion zuerst Vokale und dann Duplikate verwirft, während die erweiterte Version umgekehrt vorgeht.

- ``expr1` SOUNDS LIKE `expr2``

  Dies ist das Gleiche wie `SOUNDEX(`expr1`) = SOUNDEX(`expr2`)`.

- `SPACE(`N`)`

  Gibt einen String zurück, der aus `N` Leerzeichen besteht.

      mysql> SELECT SPACE(6);
              -> '      '

- `SUBSTRING(`str`,`pos`)`, `SUBSTRING(`str` FROM `pos`)`, `SUBSTRING(`str`,`pos`,`len`)`, `SUBSTRING(`str` FROM `pos` FOR `len`)`

  Die Formen ohne `len`-Argument geben einen Teil-String des Strings `str` zurück, der an der Position `pos` beginnt. Die Formen mit `len`-Argument geben einen Teil-String des Strings `str` mit einer Länge von `len` Zeichen zurück, der an der Position `pos` beginnt. Die Formen, die `FROM` verwenden, sind SQL-Standardsyntax. Es ist auch möglich, einen negativen Wert für `pos` zu verwenden. In diesem Fall liegt der Anfang des Teil-Strings `pos` Zeichen vom Ende des Strings (statt von seinem Anfang) entfernt. Ein negativer Wert kann für `pos` in allen Formen dieser Funktion verwendet werden.

      mysql> SELECT SUBSTRING('Quadratically',5);
              -> 'ratically'
      mysql> SELECT SUBSTRING('foobarbar' FROM 4);
              -> 'barbar'
      mysql> SELECT SUBSTRING('Quadratically',5,6);
              -> 'ratica'
      mysql> SELECT SUBSTRING('Sakila', -3);
              -> 'ila'
      mysql> SELECT SUBSTRING('Sakila', -5, 3);
              -> 'aki'
      mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
              -> 'ki'

  Diese Funktion ist multibytesicher.

  Wenn `len` kleiner als 1 ist, wird der Leer-String zurückgegeben.

  `SUBSTR()` ist ein Synonym für `SUBSTRING()`.

- `SUBSTRING_INDEX(`str`,`delim`,`count`)`

  Gibt einen Teil-String des Strings `str` zurück. Der Teil-String umfasst den Teil des Strings vom Anfang bis zum `count`-sten Auftreten des Trennzeichens `delim`. Wenn `count` positiv ist, wird alles links vom (von links gezählt) letzten Trennzeichen zurückgegeben. Wenn `count` negativ ist, wird alles rechts vom (von rechts gezählt) letzten Trennzeichen zurückgegeben. `SUBSTRING_INDEX()` führt bei der Suche nach `delim` einen Vergleich unter Berücksichtigung der Groß-/Kleinschreibung durch.

      mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
              -> 'www.mysql'
      mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
              -> 'mysql.com'

  Diese Funktion ist multibytesicher.

- `TRIM([{BOTH | LEADING | TRAILING} [`remstr`] FROM] `str`)`, `TRIM(`remstr` FROM] `str`)`

  Gibt den String `str` zurück, bei dem alle `remstr`-Präfixe oder -Suffixe entfernt wurden. Wenn keine der Konfigurationsangaben `BOTH`, `LEADING` oder `TRAILING` angegeben wurde, wird `BOTH` vorausgesetzt. `remstr` ist optional; sofern es nicht angegeben ist, werden Leerzeichen entfernt.

      mysql> SELECT TRIM('  bar   ');
              -> 'bar'
      mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
              -> 'barxxx'
      mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
              -> 'bar'
      mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
              -> 'barx'

  Diese Funktion ist multibytesicher.

- `UCASE(`str`)`

  `UCASE()` ist ein Synonym für `UPPER()`.

- `UNHEX(`str`)`

  Führt die umgekehrte Operation von `HEX(`str`)` durch: Jedes Paar Hexadezimalziffern im Argument wird als Zahl interpretiert und in das Zeichen umgewandelt, das durch die Zahl dargestellt wird. Das Ergebnis wird als Binär-String zurückgegeben.

      mysql> SELECT UNHEX('4D7953514C');
              -> 'MySQL'
      mysql> SELECT 0x4D7953514C;
              -> 'MySQL'
      mysql> SELECT UNHEX(HEX('string'));
              -> 'string'
      mysql> SELECT HEX(UNHEX('1267'));
              -> '1267'

- `UPPER(`str`)`

  Gibt den String `str` mit allen Zeichen zurück, die aufgrund der aktuellen Zeichensatzzuordnung in Großbuchstaben umgewandelt wurden. Der Standardzeichensatz ist `latin1` (cp1252 West European).

      mysql> SELECT UPPER('Hej');
              -> 'HEJ'

  Diese Funktion ist multibytesicher.

### 12.3.1. String-Vergleichsfunktionen

Wenn einer String-Funktion ein Binär-String als Argument übergeben wird, ist der Ergebnis-String ebenfalls ein Binär-String. Eine Zahl, die in einen String konvertiert wird, wird als Binär-String behandelt. Dies betrifft nur Vergleiche.

Wenn ein Ausdruck in einem String-Vergleich die Groß-/Kleinschreibung unterscheidet, dann wird der Vergleich ebenfalls mit Unterscheidung der Groß-/Kleinschreibung durchgeführt.

- ``expr` LIKE `pat` [ESCAPE '`escape_char`']`

  Mustervergleich unter Verwendung eines einfachen SQL-Vergleichs mit regulären Ausdrücken. Gibt `1` (`TRUE`) oder `0` (`FALSE`) zurück. Wenn entweder `expr` oder `pat` `NULL` sind, ist das Ergebnis `NULL`.

  Das Muster muss kein literaler String sein. Es kann beispielsweise auch als String-Ausdruck oder als Tabellenspalte angegeben werden.

  Gemäß dem SQL-Standard führt `LIKE` die Überprüfung auf Zeichenbasis durch, kann also Ergebnisse erzeugen, die sich von denen des Vergleichsoperators `=` unterscheiden:

      mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
      +-----------------------------------------+
      | 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
      +-----------------------------------------+
      |                                       0 |
      +-----------------------------------------+
      mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
      +--------------------------------------+
      | 'ä' = 'ae' COLLATE latin1_german2_ci |
      +--------------------------------------+
      |                                    1 |
      +--------------------------------------+

  Bei `LIKE` können Sie die folgenden beiden Jokerzeichen im Muster verwenden:

  Zeichen | Beschreibung
  `%` | entspricht einer beliebigen Anzahl von Zeichen (einschließlich null Zeichen).
  `_` | entspricht genau einem Zeichen.

      mysql> SELECT 'David!' LIKE 'David_';
              -> 1
      mysql> SELECT 'David!' LIKE '%D%v%';
              -> 1

  Um auf literale Instanzen eines Jokerzeichens zu prüfen, stellen Sie ihm ein Escape-Zeichen voran. Wenn Sie das Escape-Zeichen nicht angeben, wird ‘`\`’ angenommen.

  String | Beschreibung
  `\%` | entspricht einem ‘`%`’-Zeichen.
  `\_` | entspricht einem ‘`_`’-Zeichen.

      mysql> SELECT 'David!' LIKE 'David\_';
              -> 0
      mysql> SELECT 'David_' LIKE 'David\_';
              -> 1

  Um ein anderes Escape-Zeichen anzugeben, verwenden Sie die `ESCAPE`-Klausel:

      mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
              -> 1

  Die Escape-Sequenz sollte leer oder genau ein Zeichen lang sein. Ab MySQL 5.1.2 darf die Sequenz nicht leer sein, wenn der SQL-Modus `NO_BACKSLASH_ESCAPES` aktiviert wurde.

  Die folgenden beiden Anweisungen veranschaulichen, dass die Groß-/Kleinschreibung bei String-Vergleichen nicht unterschieden wird, sofern nicht einer der Operanden ein Binär-String ist:

      mysql> SELECT 'abc' LIKE 'ABC';
              -> 1
      mysql> SELECT 'abc' LIKE BINARY 'ABC';
              -> 0

  In MySQL ist `LIKE` für numerische Ausdrücke zulässig. (Dies stellt eine Erweiterung zu `LIKE` nach SQL-Standard dar.)

      mysql> SELECT 10 LIKE '1%';
              -> 1

  Hinweis: Weil MySQL die C-Escape-Syntax in Strings verwendet (z. B. ‘`\n`’ zur Darstellung eines Zeilenwechsels), müssen Sie jedes ‘`\`’, das Sie in `LIKE`-Strings verwenden, verdoppeln. Um beispielsweise nach ‘`\n`’ zu suchen, geben Sie es als ‘`\\n`’ an. Um nach ‘`\`’ zu suchen, geben Sie es als ‘`\\\\`’ an; dies ist erforderlich, weil Backslashs einmal vom Parser und dann noch einmal bei Durchführung des Mustervergleichs umgewandelt werden – so bleibt für den Vergleich ein einzelner Backslash übrig.

- ``expr` NOT LIKE `pat` [ESCAPE '`escape_char`']`

  Dies ist das Gleiche wie `NOT (`expr` LIKE `pat` [ESCAPE '`escape_char`'])`.

- ``expr` NOT REGEXP `pat``, ``expr` NOT RLIKE `pat``

  Dies ist das Gleiche wie `NOT (`expr` REGEXP `pat`)`.

- ``expr` REGEXP `pat`` ``expr` RLIKE `pat``

  Führt einen Mustervergleich eines String-Ausdrucks `expr` mit einem Muster `pat` durch. Das Muster kann ein erweiterter regulärer Ausdruck sein. Die Syntax für reguläre Ausdrücke wird in Anhang G, Beschreibung der MySQL-Syntax für reguläre Ausdrücke, beschrieben. Gibt `1` zurück, wenn `expr` mit `pat` übereinstimmt; andernfalls wird `0` zurückgegeben. Wenn entweder `expr` oder `pat` `NULL` sind, ist das Ergebnis auch `NULL`. `RLIKE` ist ein Synonym für `REGEXP`, welches aus Gründen der `mSQL`-Kompatibilität vorhanden ist.

  Das Muster muss kein literaler String sein. Es kann beispielsweise auch als String-Ausdruck oder als Tabellenspalte angegeben werden.

  Hinweis: Weil MySQL die C-Escape-Syntax in Strings verwendet (z. B. ‘`\n`’ zur Darstellung eines Zeilenwechsels), müssen Sie jedes ‘`\`’, das Sie in `REGEXP`-Strings verwenden, verdoppeln.

  `REGEXP` unterscheidet die Groß-/Kleinschreibung nur dann, wenn sie mit Binär-Strings verwendet wird.

      mysql> SELECT 'Monty!' REGEXP 'm%y%%';
              -> 0
      mysql> SELECT 'Monty!' REGEXP '.*';
              -> 1
      mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
              -> 1
      mysql> SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
              -> 1  0
      mysql> SELECT 'a' REGEXP '^[a-d]';
              -> 1

  `REGEXP` und `RLIKE` verwenden zur Erkennung des Typs eines Zeichens den aktuellen Zeichensatz. Der Standardzeichensatz ist `latin1` (cp1252 West European). Warnung: Diese Operatoren sind nicht multibytesicher.

- `STRCMP(`expr1`,`expr2`)`

  `STRCMP()` gibt `0` zurück, wenn die Strings identisch sind, `-1`, wenn das erste Argument entsprechend der aktuellen Sortierreihenfolge kleiner ist als das zweite, und `1` in jedem anderen Fall.

      mysql> SELECT STRCMP('text', 'text2');
              -> -1
      mysql> SELECT STRCMP('text2', 'text');
              -> 1
      mysql> SELECT STRCMP('text', 'text');
              -> 0

  `STRCMP()` verwendet zur Durchführung von Vergleichsoperationen den aktuellen Zeichensatz. Insofern wird die Groß-/Kleinschreibung bei Vergleichen standardmäßig nicht unterschieden, sofern nicht mindestens einer der Operanden ein Binär-String ist.

## 12.4. Numerische Funktionen

### 12.4.1. Arithmetische Operationen

Es stehen die normalen arithmetischen Operatoren zur Verfügung. Beachten Sie, dass das Ergebnis im Fall von `-`, `+` und `*` mit `BIGINT`-Genauigkeit (64-Bit-Genauigkeit) berechnet wird, sofern beide Argumente Integers sind. Wenn eines der Argumente ein vorzeichenloser Integer und das andere auch ein Integer ist, dann ist das Ergebnis ein vorzeichenloser Integer. Siehe auch Abschnitt 12.8, „Cast-Funktionen und Operatoren“.

- `+`

  Addition:

      mysql> SELECT 3+5;
              -> 8

- `-`

  Subtraktion:

      mysql> SELECT 3-5;
              -> -2

- `-`

  Monadisches Minus. Dieser Operator ändert das Vorzeichen des Arguments.

      mysql> SELECT - 2;
              -> -2

  Hinweis: Wenn der Operator mit einem `BIGINT` verwendet wird, ist der Rückgabewert ebenfalls ein `BIGINT`. Das bedeutet, dass Sie die Verwendung von `–` bei Integers vermeiden sollten, die den Wert –263 annehmen könnten.

- `*`

  Multiplikation:

      mysql> SELECT 3*5;
              -> 15
      mysql> SELECT 18014398509481984*18014398509481984.0;
              -> 324518553658426726783156020576256.0
      mysql> SELECT 18014398509481984*18014398509481984;
              -> 0

  Das Ergebnis des letzten Ausdrucks ist falsch, weil das Ergebnis der Integer-Multiplikation den 64-Bit-Bereich von `BIGINT`-Berechnungen überschreitet. (Siehe auch Abschnitt 11.2, „Numerische Datentypen“.)

- `/`

  Division:

      mysql> SELECT 3/5;
              -> 0.60

  Die Division durch null erzeugt das Ergebnis `NULL`:

      mysql> SELECT 102/(1-1);
              -> NULL

  Eine Division wird nur dann mit `BIGINT`-Arithmetik berechnet, wenn sie in einem Kontext durchgeführt wird, in dem das Ergebnis in einen Integer konvertiert wird.

- `DIV`

  Integer-Division. Ähnlich wie `FLOOR()`, aber sicher bei `BIGINT`-Werten.

      mysql> SELECT 5 DIV 2;
              -> 2

### 12.4.2. Mathematische Funktionen

Alle mathematischen Funktionen geben im Fehlerfall `NULL` zurück.

- `ABS(`X`)`

  Gibt den absoluten Wert von `X` zurück.

      mysql> SELECT ABS(2);
              -> 2
      mysql> SELECT ABS(-32);
              -> 32

  Diese Funktion kann sicher mit `BIGINT`-Werten eingesetzt werden.

- `ACOS(`X`)`

  Gibt den Arkuskosinus von `X` zurück, d. h. den Wert, dessen Kosinus `X` ist. Gibt `NULL` zurück, wenn `X` nicht im Bereich zwischen `-1` und `1` liegt.

      mysql> SELECT ACOS(1);
              -> 0
      mysql> SELECT ACOS(1.0001);
              -> NULL
      mysql> SELECT ACOS(0);
              -> 1.5707963267949

- `ASIN(`X`)`

  Gibt den Arkussinus von `X` zurück, d. h. den Wert, dessen Sinus `X` ist. Gibt `NULL` zurück, wenn `X` nicht im Bereich zwischen `-1` und `1` liegt.

      mysql> SELECT ASIN(0.2);
              -> 0.20135792079033
      mysql> SELECT ASIN('foo');

      +-------------+
      | ASIN('foo') |
      +-------------+
      |           0 |
      +-------------+
      1 row in set, 1 warning (0.00 sec)

      mysql> SHOW WARNINGS;
      +---------+------+-----------------------------------------+
      | Level   | Code | Message                                 |
      +---------+------+-----------------------------------------+
      | Warning | 1292 | Truncated incorrect DOUBLE value: 'foo' |
      +---------+------+-----------------------------------------+

- `ATAN(`X`)`

  Gibt den Arkustangens von `X` zurück, d. h. den Wert, dessen Tangens `X` ist.

      mysql> SELECT ATAN(2);
              -> 1.1071487177941
      mysql> SELECT ATAN(-2);
              -> -1.1071487177941

- `ATAN(`Y`,`X`)`, `ATAN2(`Y`,`X`)`

  Gibt den Arkustangens der beiden Variablen `X` und `Y` zurück. Dies ähnelt der Berechnung des Arkustangens von ``Y` / `X``; der einzige Unterschied besteht darin, dass die Vorzeichen beider Argumente zur Bestimmung des Quadranten des Ergebnisses verwendet werden.

      mysql> SELECT ATAN(-2,2);
              -> -0.78539816339745
      mysql> SELECT ATAN2(PI(),0);
              -> 1.5707963267949

- `CEILING(`X`)`, `CEIL(`X`)`

  Gibt den kleinsten Integer-Wert zurück, der nicht kleiner als `X` ist.

      mysql> SELECT CEILING(1.23);
              -> 2
      mysql> SELECT CEIL(-1.23);
              -> -1

  Diese beiden Funktionen sind synonym. Beachten Sie, dass der Rückgabewert in ein `BIGINT` konvertiert wird.

- `COS(`X`)`

  Gibt den Kosinus von `X` zurück, wobei `X` in rad angegeben wird.

      mysql> SELECT COS(PI());
              -> -1

- `COT(`X`)`

  Gibt den Kotangens von `X` zurück.

      mysql> SELECT COT(12);
              -> -1.5726734063977
      mysql> SELECT COT(0);
              -> NULL

- `CRC32(`expr`)`

  Berechnet einen Prüfsummenwert (CRC, Cyclic Redundancy Check) und gibt einen vorzeichenlosen 32-Bit-Wert zurück. Das Ergebnis ist `NULL`, wenn das Argument `NULL` ist. Als Argument wird ein String erwartet, der dann (sofern möglich) so behandelt wird, als wäre er keiner.

      mysql> SELECT CRC32('MySQL');
              -> 3259397556
      mysql> SELECT CRC32('mysql');
              -> 2501908538

- `DEGREES(`X`)`

  Gibt das Argument `X` umgewandelt von rad in Grad zurück.

      mysql> SELECT DEGREES(PI());
              -> 180
      mysql> SELECT DEGREES(PI() / 2);
              -> 90

- `EXP(`X`)`

  Gibt den Wert von e (Basis natürlicher Logarithmen) zur Potenz `X` zurück.

      mysql> SELECT EXP(2);
              -> 7.3890560989307
      mysql> SELECT EXP(-2);
              -> 0.13533528323661
      mysql> SELECT EXP(0);
              -> 1

- `FLOOR(`X`)`

  Gibt den größten Integer-Wert zurück, der nicht größer als `X` ist.

      mysql> SELECT FLOOR(1.23);
              -> 1
      mysql> SELECT FLOOR(-1.23);
              -> -2

  Beachten Sie, dass der Rückgabewert in ein `BIGINT` konvertiert wird.

- `FORMAT(`X`,`D`)`

  Formatiert die Zahl `X` in ein Format wie `'#,###,###.##'`, gerundet auf `D` Dezimalstellen, und gibt das Ergebnis als String zurück. Detaillierte Informationen finden Sie in Abschnitt 12.3, „String-Funktionen“.

- `LN(`X`)`

  Gibt den natürlichen Logarithmus von `X` zurück, d. h. den Logarithmus von `X` zur Basis e.

      mysql> SELECT LN(2);
              -> 0.69314718055995
      mysql> SELECT LN(-2);
              -> NULL

  Diese Funktion ist synonym zu `LOG(`X`)`.

- `LOG(`X`)`, `LOG(`B`,`X`)`

  Sofern mit einem Parameter aufgerufen, gibt diese Funktion den natürlichen Logarithmus von `X` zurück.

      mysql> SELECT LOG(2);
              -> 0.69314718055995
      mysql> SELECT LOG(-2);
              -> NULL

  Wenn der Aufruf mit zwei Parametern erfolgt, gibt die Funktion den Logarithmus von `X` zur (beliebig anzugebenden) Basis `B` zurück.

      mysql> SELECT LOG(2,65536);
              -> 16
      mysql> SELECT LOG(10,100);
              -> 2

  `LOG(`B`,`X`)` ist äquivalent mit `LOG(`X`) / LOG(`B`)`.

- `LOG2(`X`)`

  Gibt den Logarithmus von ``X`` zur Basis 2 zurück.

      mysql> SELECT LOG2(65536);
              -> 16
      mysql> SELECT LOG2(-100);
              -> NULL

  `LOG2()` ist praktisch, um zu ermitteln, wie viele Bits eine Zahl zur Speicherung benötigt. Die Funktion ist äquivalent zu dem Ausdruck `LOG(`X`) / LOG(2)`.

- `LOG10(`X`)`

  Gibt den Logarithmus von `X` zur Basis 10 zurück.

      mysql> SELECT LOG10(2);
              -> 0.30102999566398
      mysql> SELECT LOG10(100);
              -> 2
      mysql> SELECT LOG10(-100);
              -> NULL

  `LOG10(`X`)` ist äquivalent mit `LOG(10,`X`)`.

- `MOD(`N`,`M`)`, ``N` % `M``, ``N` MOD `M``

  Modulooperation. Gibt den Rest von `N` geteilt durch `M` zurück.

      mysql> SELECT MOD(234, 10);
              -> 4
      mysql> SELECT 253 % 7;
              -> 1
      mysql> SELECT MOD(29,9);
              -> 2
      mysql> SELECT 29 MOD 9;
              -> 2

  Diese Funktion kann mit `BIGINT`-Werten sicher eingesetzt werden.

  `MOD()` funktioniert auch bei Werten mit Nachkommastellen und gibt den exakten Rest nach der Division zurück:

      mysql> SELECT MOD(34.5,3);
              -> 1.5

- `PI()`

  Gibt den Wert von π (Pi) zurück. Standardmäßig werden sieben Dezimalstellen angezeigt, MySQL verwendet intern jedoch den vollständigen Wert doppelter Genauigkeit.

      mysql> SELECT PI();
              -> 3.141593
      mysql> SELECT PI()+0.000000000000000000;
              -> 3.141592653589793116

- `POW(`X`,`Y`)`, `POWER(`X`,`Y`)`

  Gibt den Wert von `X` potenziert zu `Y` an.

      mysql> SELECT POW(2,2);
              -> 4
      mysql> SELECT POW(2,-2);
              -> 0.25

- `RADIANS(`X`)`

  Gibt das Argument `X` umgewandelt von Grad in rad zurück. (Beachten Sie, dass π rad 180 Grad entspricht.)

      mysql> SELECT RADIANS(90);
              -> 1.5707963267949

- `RAND()`, `RAND(`N`)`

  Gibt einen zufälligen Fließkommawert `v` zwischen `0` und `1` inklusive (d. h. im Bereich `0` <= `v` <= `1.0`) zurück. Wenn ein Integer-Argument `N` angegeben ist, wird es als Ausgangswert verwendet, der eine wiederholbare Sequenz erzeugt.

      mysql> SELECT RAND();
              -> 0.9233482386203
      mysql> SELECT RAND(20);
              -> 0.15888261251047
      mysql> SELECT RAND(20);
              -> 0.15888261251047
      mysql> SELECT RAND();
              -> 0.63553050033332
      mysql> SELECT RAND();
              -> 0.70100469486881
      mysql> SELECT RAND(20);
              -> 0.15888261251047

  Um einen zufälligen Integer `R` im Bereich `i` <= `R` <= `j` zu erhalten, verwenden Sie den Ausdruck `FLOOR(`i`+ RAND() * (`j`– `i`+ 1))`. Um beispielsweise einen ganzzahligen Zufallswert im Bereich zwischen 7 und 12 (einschließlich) zu erhalten, können Sie die folgende Anweisung verwenden:

      SELECT FLOOR(7 + (RAND() * 6));

  Sie können eine Spalte mit `RAND()`-Werten nicht in einer `ORDER BY`-Klausel angeben, weil `ORDER BY` die Spalte mehrfach auswerten würde. Allerdings können Sie Datensätze in zufälliger Folge abrufen. Das funktioniert wie folgt:

      mysql> SELECT * FROM tbl_name ORDER BY RAND();

  `ORDER BY RAND()` in Kombination mit `LIMIT` ist nützlich zur Auswahl eines Zufallswerts aus einer Datensatzmenge:

      mysql> SELECT * FROM table1, table2 WHERE a=b AND c<d -> ORDER BY RAND() LIMIT 1000;

  Beachten Sie, dass `RAND()` in einer `WHERE`-Klausel jedes Mal, wenn `WHERE` ausgeführt wird, neu ausgewertet wird.

  `RAND()` ist nicht als perfekter Zufallsgenerator gedacht, sondern stellt eine gute Möglichkeit da, ad hoc Zufallszahlen zu erzeugen, die innerhalb derselben MySQL-Version plattformübergreifend funktioniert.

- `ROUND(`X`)`, `ROUND(`X`,`D`)`

  Gibt das Argument `X` gerundet auf den nächstgelegenen Integer zurück. Bei zwei übergebenen Argumenten wird `X` gerundet auf `D` Dezimalstellen zurückgegeben. `D` kann negativ sein; in diesem Fall werden `D` Stellen links des Dezimalpunkts des Werts `X` null.

      mysql> SELECT ROUND(-1.23);
              -> -1
      mysql> SELECT ROUND(-1.58);
              -> -2
      mysql> SELECT ROUND(1.58);
              -> 2
      mysql> SELECT ROUND(1.298, 1);
              -> 1.3
      mysql> SELECT ROUND(1.298, 0);
              -> 1
      mysql> SELECT ROUND(23.298, -1);
              -> 20

  Der Rückgabetyp ist derselbe wie der des ersten Arguments (vorausgesetzt, dies ist ein Integer, eine Fließkommazahl oder eine Dezimalzahl). Das bedeutet, dass bei einem Integer-Argument das Ergebnis ein Integer ist (der keine Dezimalstellen aufweist).

  `ROUND()` verwendet für genaue Zahlen die Precision-Math-Bibliothek, wenn das erste Argument ein Dezimalwert ist:

  - Bei genauen Zahlen verwendet `ROUND()` die gängigen Rundungsregeln: Ein Wert mit einem Wert von 5 oder größer nach dem Komma wird auf den nächsten Integer aufgerundet bzw. (bei negativen Werten) abgerundet. (Anders gesagt: Die Rundung erfolgt von Null weg.) Ein Wert mit einem Wert von weniger als 5 nach dem Komma wird auf den nächsten Integer abgerundet bzw. (bei negativen Werten) aufgerundet.

  - Bei Näherungswerten hängt das Ergebnis von der C-Bibliothek ab. Auf vielen Systemen bedeutet dies, dass `ROUND()` die Regel „auf nächste gerade Zahl aufrunden“ einsetzt: Ein Wert mit Nachkommastellen wird auf den nächsten geraden Integer gerundet.

  Das folgende Beispiel zeigt, wie die Rundung sich bei exakten und bei Näherungswerten voneinander unterscheidet:

      mysql> SELECT ROUND(2.5), ROUND(25E-1);
      +------------+--------------+
      | ROUND(2.5) | ROUND(25E-1) |
      +------------+--------------+
      | 3          |            2 |
      +------------+--------------+

  Weitere Informationen finden Sie unter Kapitel 23, Präzisionsberechnungen.

- `SIGN(`X`)`

  Gibt das Vorzeichen des Arguments als `-1`, `0` oder `1` abhängig davon zurück, ob `X` negativ, null oder positiv ist.

      mysql> SELECT SIGN(-32);
              -> -1
      mysql> SELECT SIGN(0);
              -> 0
      mysql> SELECT SIGN(234);
              -> 1

- `SIN(`X`)`

  Gibt den Sinus von `X` zurück, wobei `X` in rad angegeben wird.

      mysql> SELECT SIN(PI());
              -> 1.2246063538224e-16
      mysql> SELECT ROUND(SIN(PI()));
              -> 0

- `SQRT(`X`)`

  Gibt die Quadratwurzel einer nichtnegativen Zahl `X` zurück.

      mysql> SELECT SQRT(4);
              -> 2
      mysql> SELECT SQRT(20);
              -> 4.4721359549996
      mysql> SELECT SQRT(-16);
              -> NULL

- `TAN(`X`)`

  Gibt den Tangens von `X` zurück, wobei `X` in rad angegeben wird.

      mysql> SELECT TAN(PI());
              -> -1.2246063538224e-16
      mysql> SELECT TAN(PI()+1);
              -> 1.5574077246549

- `TRUNCATE(`X`,`D`)`

  Gibt die Zahl `X` auf `D` Dezimalstellen beschnitten zurück. Wenn `D` `0` ist, hat das Ergebnis keinen Dezimalpunkt und keine Nachkommastellen. `D` kann auch negativ sein. In diesem Fall werden `D` Stellen links vom Dezimalpunkt des Werts `X` null.

      mysql> SELECT TRUNCATE(1.223,1);
              -> 1.2
      mysql> SELECT TRUNCATE(1.999,1);
              -> 1.9
      mysql> SELECT TRUNCATE(1.999,0);
              -> 1
      mysql> SELECT TRUNCATE(-1.999,1);
              -> -1.9
      mysql> SELECT TRUNCATE(122,-2);
             -> 100
      mysql> SELECT TRUNCATE(10.28*100,0);
             -> 1028

  Alle Zahlen werden nach null hin gerundet.

## 12.5. Datums- und Zeitfunktionen

Dieser Abschnitt beschreibt die Funktionen, die zur Manipulation von zeitbezogenen Werten verwendet werden können. Eine Beschreibung der Wertebereiche für Datums- und Uhrzeittypen und der gültigen Formate, in denen Werte angegeben werden können, finden Sie in Abschnitt 11.3, „Datums- und Zeittypen“.

Es folgt ein Beispiel, welches Datumsfunktionen verwendet. Die folgende Abfrage wählt alle Datensätze aus, die einen `date_col`-Wert haben, der in den letzten 30 Tagen liegt:

    mysql> SELECT something FROM tbl_name
        -> WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date_col;

Beachten Sie, dass die Abfrage auch Datensätze mit Daten auswählt, die in der Zukunft liegen.

Funktionen, die Datumswerte erwarten, akzeptieren normalerweise auch `DATETIME`-Werte und ignorieren dabei den Uhrzeitbestandteil. Ähnlich akzeptieren Funktionen, die Zeitwerte erwarten, normalerweise auch `DATETIME`-Werte und ignorieren den Datumsbestandteil.

Funktionen, die das aktuelle Datum oder die Uhrzeit zurückgeben, werden nur einmal pro Abfrage ausgewertet, nämlich beim Start der Abfrageausführung. Das bedeutet, dass mehrere Referenzierungen einer Funktion wie `NOW()` in einer Abfrage immer zum selben Ergebnis führen (für unsere Zwecke enthält eine einzelne Abfrage auch einen Aufruf einer gespeicherten Routine oder eines Triggers sowie alle Subroutinen, die von dieser Routine oder diesem Trigger aufgerufen werden). Dieses Prinzip gilt auch für `CURDATE()`, `CURTIME()`, `UTC_DATE()`, `UTC_TIME()`, `UTC_TIMESTAMP()` und für alle zugehörigen Synonyme.

Die Funktionen `CURRENT_TIMESTAMP()`, `CURRENT_TIME()`, `CURRENT_DATE()` und `FROM_UNIXTIME()` geben Werte in der aktuellen Zeitzone der Verbindung zurück, die als Wert der Systemvariablen `time_zone` verfügbar ist. Ferner setzt `UNIX_TIMESTAMP()` voraus, dass sein Argument ein `DATETIME`-Wert in der aktuellen Zeitzone ist. Siehe auch Abschnitt 5.11.8, „Zeitzonen-Unterstützung des MySQL-Servers“.

Einige Datumsfunktionen können mit „Nulldaten“ oder unvollständigen Daten wie `'2001-11-00'` verwendet werden, während dies bei anderen nicht möglich ist. Funktionen, die Teile von Datumsangaben extrahieren, arbeiten meist auch mit unvollständigen Daten. Zum Beispiel:

    mysql> SELECT DAYOFMONTH('2001-11-00'), MONTH('2005-00-00');
            -> 0, 0

Andere Funktionen erwarten vollständige Daten und geben `NULL` zurück, wenn unvollständige Daten übergeben werden. Hierzu gehören Funktionen, die Datumsberechnungen durchführen oder Teile von Datumsangaben Namen zuordnen. Zum Beispiel:

    mysql> SELECT DATE_ADD('2006-05-00',INTERVAL 1 DAY);
            -> NULL
    mysql> SELECT DAYNAME('2006-05-00');
            -> NULL

- `ADDDATE(`date`,INTERVAL `expr` `type`)`, `ADDDATE(`expr`,`days`)`

  Wenn mit der Form `INTERVAL` für das zweite Argument aufgerufen, ist `ADDDATE()` ein Synonym von `DATE_ADD()`. Die zugehörige Funktion `SUBDATE()` ist ein Synonym für `DATE_SUB()`. Weitere Informationen zum Argument `INTERVAL` finden Sie in der Beschreibung zu `DATE_ADD()`.

      mysql> SELECT DATE_ADD('1998-01-02', INTERVAL 31 DAY);
              -> '1998-02-02'
      mysql> SELECT ADDDATE('1998-01-02', INTERVAL 31 DAY);
              -> '1998-02-02'

  Wenn mit der Form `days` für das zweite Argument aufgerufen, wird es von MySQL als ganzzahlige Anzahl von Tagen behandelt, die `expr` hinzugefügt wird.

      mysql> SELECT ADDDATE('1998-01-02', 31);
              -> '1998-02-02'

- `ADDTIME(`expr`,`expr2`)`

  `ADDTIME()` fügt `expr2` `expr` hinzu und gibt das Ergebnis zurück. `expr` ist eine Zeitangabe oder ein `DATETIME`-Wert, `expr2` eine Zeitangabe.

      mysql> SELECT ADDTIME('1997-12-31 23:59:59.999999',
          ->                '1 1:1:1.000002');
              -> '1998-01-02 01:01:01.000001'
      mysql> SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');
              -> '03:00:01.999997'

- `CONVERT_TZ(`dt`,`from_tz`,`to_tz`)`

  `CONVERT_TZ()` wandelt einen `DATETIME`-Wert `dt` von der angegebenen Ausgangszeitzone `from_tz` in die Zielzeitzone `to_tz` um und gibt das Ergebnis zurück. Zeitzonen werden wie in Abschnitt 5.11.8, „Zeitzonen-Unterstützung des MySQL-Servers“, beschrieben angegeben. Die Funktion gibt `NULL` zurück, wenn die Argumente ungültig sind.

  Fiele der Wert durch die Konvertierung aus `from_tz` in UTC außerhalb des vom Typ `TIMESTAMP` unterstützten Bereichs, dann erfolgt keine Konvertierung. Der für `TIMESTAMP` gültige Bereich ist in Abschnitt 11.1.2, „Überblick über Datums- und Zeittypen“, beschrieben.

      mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
              -> '2004-01-01 13:00:00'
      mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
              -> '2004-01-01 22:00:00'

  Hinweis: Wenn Sie benannte Zeitzonen wie `'MET'` oder `'Europe/Moscow'` verwenden wollen, müssen die Zeitzonentabellen korrekt konfiguriert sein. Eine Anleitung finden Sie in Abschnitt 5.11.8, „Zeitzonen-Unterstützung des MySQL-Servers“.

- `CURDATE()`

  Gibt das aktuelle Datum als Wert in den Formaten `'YYYY-MM-DD'` oder `YYYYMMDD` aus. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird.

      mysql> SELECT CURDATE();
              -> '1997-12-15'
      mysql> SELECT CURDATE() + 0;
              -> 19971215

- `CURRENT_DATE`, `CURRENT_DATE()`

  `CURRENT_DATE` und `CURRENT_DATE()` sind Synonyme von `CURDATE()`.

- `CURTIME()`

  Gibt die aktuelle Uhrzeit als Wert in den Formaten `'HH:MM:SS'` oder `HHMMSS` aus. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird.

      mysql> SELECT CURTIME();
              -> '23:50:26'
      mysql> SELECT CURTIME() + 0;
              -> 235026

- `CURRENT_TIME`, `CURRENT_TIME()`

  `CURRENT_TIME` und `CURRENT_TIME()` sind Synonyme von `CURTIME()`.

- `CURRENT_TIMESTAMP`, `CURRENT_TIMESTAMP()`

  `CURRENT_TIMESTAMP` und `CURRENT_TIMESTAMP()` sind Synonyme von `NOW()`.

- `DATE(`expr`)`

  Extrahiert den Datumsteil aus dem `DATE`- oder `DATETIME`-Ausdruck `expr`.

      mysql> SELECT DATE('2003-12-31 01:02:03');
              -> '2003-12-31'

- `DATEDIFF(`expr`,`expr2`)`

  `DATEDIFF()` gibt die Anzahl der Tage zwischen dem Startdatum `expr` und dem Enddatum `expr2` zurück. `expr` und `expr2` sind `DATE`- oder `DATETIME`-Ausdrücke. Nur die Datumsanteile der Werte werden in der Berechnung verwendet.

      mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
              -> 1
      mysql> SELECT DATEDIFF('1997-11-30 23:59:59','1997-12-31');
              -> -31

- `DATE_ADD(`date`,INTERVAL `expr` `type`)`, `DATE_SUB(`date`,INTERVAL `expr` `type`)`

  Diese Funktionen führen Datumsberechnungen durch. `date` ist ein `DATETIME`- oder `DATE`-Wert, der das Startdatum angibt. `expr` ist ein Ausdruck, der den vom Startdatum hinzuzufügenden oder abzuziehenden Intervallwert angibt. `expr` ist dabei ein String und kann bei negativen Intervallen mit einem ‘`-`’ beginnen. `type` ist ein Schlüsselwort, das angibt, wie der Ausdruck zu interpretieren ist.

  Das Schlüsselwort `INTERVAL` und die Angabe `type` unterscheiden die Groß-/Kleinschreibung nicht.

  Die folgende Tabelle zeigt die erwartete Form des Arguments `expr` für die einzelnen `type`-Werte.

  `type` Wert | Erwartetes `expr`-Format
  `MICROSECOND` | `MICROSECONDS`
  `SECOND` | `SECONDS`
  `MINUTE` | `MINUTES`
  `HOUR` | `HOURS`
  `DAY` | `DAYS`
  `WEEK` | `WEEKS`
  `MONTH` | `MONTHS`
  `QUARTER` | `QUARTERS`
  `YEAR` | `YEARS`
  `SECOND_MICROSECOND` | `'SECONDS.MICROSECONDS'`
  `MINUTE_MICROSECOND` | `'MINUTES.MICROSECONDS'`
  `MINUTE_SECOND` | `'MINUTES:SECONDS'`
  `HOUR_MICROSECOND` | `'HOURS.MICROSECONDS'`
  `HOUR_SECOND` | `'HOURS:MINUTES:SECONDS'`
  `HOUR_MINUTE` | `'HOURS:MINUTES'`
  `DAY_MICROSECOND` | `'DAYS.MICROSECONDS'`
  `DAY_SECOND` | `'DAYS HOURS:MINUTES:SECONDS'`
  `DAY_MINUTE` | `'DAYS HOURS:MINUTES'`
  `DAY_HOUR` | `'DAYS HOURS'`
  `YEAR_MONTH` | `'YEARS-MONTHS'`

  MySQL erlaubt die Verwendung beliebiger Interpunktionszeichen als Trennzeichen im Format von `expr`. Die in der Tabelle gezeigten Trennzeichen sind als Vorschläge aufzufassen. Wenn das Argument `date` ein `DATE`-Wert ist und Ihre Berechnungen nur die Teile `YEAR`, `MONTH` und `DAY` (also keine uhrzeitbezogenen Teile) betreffen, ist das Ergebnis ein `DATE`-Wert. Andernfalls ist das Ergebnis ein `DATETIME`-Wert.

  Datumsberechnungen können auch mit `INTERVAL` in Kombination mit den Operatoren `+` und `-` durchgeführt werden:

      date + INTERVAL expr type
      date - INTERVAL expr type

  `INTERVAL `expr` `type`` ist auf beiden Seiten des Operators `+` zulässig, wenn der Ausdruck auf der jeweils anderen Seite ein `DATE`- oder `DATETIME`-Wert ist. Beim Operator `-` ist `INTERVAL `expr` `type`` nur auf der rechten Seite der Gleichung zulässig, da das Abziehen eines `DATE`- oder `DATETIME`-Werts von einem Intervall unsinnig wäre.

      mysql> SELECT '1997-12-31 23:59:59' + INTERVAL 1 SECOND;
              -> '1998-01-01 00:00:00'
      mysql> SELECT INTERVAL 1 DAY + '1997-12-31';
              -> '1998-01-01'
      mysql> SELECT '1998-01-01' - INTERVAL 1 SECOND;
              -> '1997-12-31 23:59:59'
      mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
          ->                 INTERVAL 1 SECOND);
              -> '1998-01-01 00:00:00'
      mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
          ->                 INTERVAL 1 DAY);
              -> '1998-01-01 23:59:59'
      mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
          ->                 INTERVAL '1:1' MINUTE_SECOND);
              -> '1998-01-01 00:01:00'
      mysql> SELECT DATE_SUB('1998-01-01 00:00:00',
          ->                 INTERVAL '1 1:1:1' DAY_SECOND);
              -> '1997-12-30 22:58:59'
      mysql> SELECT DATE_ADD('1998-01-01 00:00:00',
          ->                 INTERVAL '-1 10' DAY_HOUR);
              -> '1997-12-30 14:00:00'
      mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
              -> '1997-12-02'
      mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002',
          ->            INTERVAL '1.999999' SECOND_MICROSECOND);
              -> '1993-01-01 00:00:01.000001'

  Wenn Sie einen Intervallwert angeben, der zu kurz ist (d. h. nicht alle Intervallteile enthält, die aufgrund des Schlüsselworts `type` erwartet werden), dann geht MySQL davon aus, dass Sie den linken Teil des Intervallwerts weggelassen haben. Geben Sie also etwa als `type` `DAY_SECOND` an, dann wird erwartet, dass der Wert von `expr` Teile für Tage, Stunden, Minuten und Sekunden enthält. Bei einer Angabe `'1:10'` setzt MySQL voraus, dass die Teile für Tage und Stunden fehlen und der Wert Minuten und Sekunden angibt. Anders gesagt, wird `'1:10' DAY_SECOND` als äquivalent zu `'1:10' MINUTE_SECOND` interpretiert. Dies entspricht auch der Art und Weise, wie MySQL `TIME`-Werte als verstrichene Zeit (statt als Uhrzeit) auffasst.

  Wenn Sie etwas zu einem Datum hinzuaddieren oder davon abziehen, das einen Uhrzeitteil enthält, dann wird das Ergebnis automatisch in einen `DATETIME`-Wert umgewandelt:

      mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 DAY);
              -> '1999-01-02'
      mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 HOUR);
              -> '1999-01-01 01:00:00'

  Wenn Sie `MONTH`, `YEAR_MONTH` oder `YEAR` hinzuaddieren und das Ergebnis einen Tageswert hat, der größer ist als der letzte Tag des neuen Monats, dann wird der Tag im neuen Monat auf den letzten Tag gesetzt:

      mysql> SELECT DATE_ADD('1998-01-30', INTERVAL 1 MONTH);
              -> '1998-02-28'

  Datumsberechnungen erfordern vollständige Datumsangaben; unvollständige Angaben wie `'2005-07-00'` oder erheblich fehlerhaft formatierte Werte wie die folgenden funktionieren nicht:

      mysql> SELECT DATE_ADD('2006-07-00', INTERVAL 1 DAY);
              -> NULL
      mysql> SELECT '2005-03-32' + INTERVAL 1 MONTH;
              -> NULL

- `DATE_FORMAT(`date`,`format`)`

  Formatiert den Wert `date` entsprechend dem String `format`.

  Die folgenden Konfigurationsangaben können im String `format` verwendet werden. Das Zeichen ‘`%`’ ist vor jede Formatangabe zu setzen.

  Konfigurationsangabe | Beschreibung
  `%a` | Abgekürzter Name des Wochentags (`Sun` ... `Sat`)
  `%b` | Abgekürzter Name des Monats (`Jan` ... `Dec`)
  `%c` | Monat, numerisch (`0` ... `12`)
  `%D` | Tag im Monat mit englischem Suffix (`0th`, `1st`, `2nd`, `3rd`, …)
  `%d` | Tag im Monat, numerisch (`00` ... `31`)
  `%e` | Tag im Monat, numerisch (`0` ... `31`)
  `%f` | Mikrosekunden (`000000` ... `999999`)
  `%H` | Stunde (`00` ... `23`)
  `%h` | Stunde (`01` ... `12`)
  `%I` | Stunde (`01` ... `12`)
  `%i` | Minuten, numerisch (`00` ... `59`)
  `%j` | Tag im Jahr (`001` ... `366`)
  `%k` | Stunde (`0` ... `23`)
  `%l` | Stunde (`1` ... `12`)
  `%M` | Monatsname (`January` ... `December`)
  `%m` | Monat, numerisch (`00` ... `12`)
  `%p` | `AM` oder `PM`
  `%r` | Uhrzeit im 12-Stunden-Format (`hh:mm:ss` gefolgt von `AM` oder `PM`)
  `%S` | Sekunden (`00` ... `59`)
  `%s` | Sekunden (`00` ... `59`)
  `%T` | Uhrzeit im 24-Stunden-Format (`hh:mm:ss`)
  `%U` | Woche (`00` ... `53`), wobei Sonntag der erste Tag der Woche ist
  `%u` | Woche (`00` ... `53`), wobei Montag der erste Tag der Woche ist
  `%V` | Woche (`01` ... `53`), wobei Sonntag der erste Tag der Woche ist; wird mit `%X` verwendet
  `%v` | Woche (`01` ... `53`), wobei Montag der erste Tag der Woche ist; wird mit `%x` verwendet
  `%W` | Name des Wochentags (`Sunday` ... `Saturday`)
  `%w` | Tag in der Woche (`0`=Sonntag ... `6`=Sonnabend)
  `%X` | Jahr der Woche, wobei Sonntag der erste Tag der Woche ist, numerisch, vierstellig; wird mit `%V` verwendet
  `%x` | Jahr der Woche, wobei Montag der erste Tag der Woche ist, numerisch, vierstellig; wird mit `%v` verwendet
  `%Y` | Jahr, numerisch, vierstellig
  `%y` | Jahr, numerisch, zweistellig
  `%%` | Literales ‘`%`’-Zeichen
  `%`x`` | `x`, steht für jedes nicht oben aufgeführte ‘`x`’

  Da MySQL die Speicherung unvollständiger Daten wie `'2004-00-00'` gestattet, beginnen die Bereiche für die monats- und tagesbezogenen Konfigurationsangaben bei null.

      mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
              -> 'Saturday October 1997'
      mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
              -> '22:23:00'
      mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
                                '%D %y %a %d %m %b %j');
              -> '4th 97 Sat 04 10 Oct 277'
      mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
                                '%H %k %I %r %T %S %w');
              -> '22 22 10 10:23:00 PM 22:23:00 00 6'
      mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
              -> '1998 52'
      mysql> SELECT DATE_FORMAT('2006-06-00', '%d');
              -> '00'

- `DAY(`date`)`

  `DAY()` ist ein Synonym für `DAYOFMONTH()`.

- `DAYNAME(`date`)`

  Gibt den Namen des Wochentags für `date` zurück.

      mysql> SELECT DAYNAME('1998-02-05');
              -> 'Thursday'

- `DAYOFMONTH(`date`)`

  Gibt den Tag im Monat für `date` zurück. Der Bereich liegt zwischen `0` und `31`.

      mysql> SELECT DAYOFMONTH('1998-02-03');
              -> 3

- `DAYOFWEEK(`date`)`

  Gibt den Wochentagindex für `date` zurück (`1` = Sonntag, `2` = Montag, …, `7` = Sonnabend). Diese Indexwerte entsprechen dem ODBC-Standard.

      mysql> SELECT DAYOFWEEK('1998-02-03');
              -> 3

- `DAYOFYEAR(`date`)`

  Gibt den Tag im Jahr für `date` zurück. Der Bereich liegt zwischen `1` und `366`.

      mysql> SELECT DAYOFYEAR('1998-02-03');
              -> 34

- `EXTRACT(`type` FROM `date`)`

  Die Funktion `EXTRACT()` verwendet dieselben Angaben für den Intervalltyp wie `DATE_ADD()` oder `DATE_SUB()`, extrahiert aber Teile des Datums, statt daran Berechnungen durchzuführen.

      mysql> SELECT EXTRACT(YEAR FROM '1999-07-02');
             -> 1999
      mysql> SELECT EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03');
             -> 199907
      mysql> SELECT EXTRACT(DAY_MINUTE FROM '1999-07-02 01:02:03');
             -> 20102
      mysql> SELECT EXTRACT(MICROSECOND
          ->                FROM '2003-01-02 10:30:00.000123');
              -> 123

- `FROM_DAYS(`N`)`

  Gibt für eine Tagesanzahl `N` den `DATE`-Wert zurück.

      mysql> SELECT FROM_DAYS(729669);
              -> '1997-10-07'

  Verwenden Sie `FROM_DAYS()` bei alten Datumsangaben mit Vorsicht. Die Funktion ist nicht zur Verwendung mit Daten gedacht, die vor der Einführung des gregorianischen Kalenders (1582) liegen. Siehe auch Abschnitt 12.6, „Welchen Kalender benutzt MySQL?“.

- `FROM_UNIXTIME(`unix_timestamp`)`, `FROM_UNIXTIME(`unix_timestamp`,`format`)`

  Gibt eine Darstellung des `unix_timestamp`-Arguments als Wert in den Formaten `'YYYY-MM-DD HH:MM:SS'` oder `YYYYMMDDHHMMSS` zurück. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird. `unix_timestamp` ist ein interner Zeitstempelwert, der von der Funktion `UNIX_TIMESTAMP()` erzeugt wird.

  Wenn `format` angegeben ist, wird das Ergebnis entsprechend dem String `format` formatiert, der so verwendet wird wie im Abschnitt zur Funktion `DATE_FORMAT()` beschrieben.

      mysql> SELECT FROM_UNIXTIME(875996580);
              -> '1997-10-04 22:23:00'
      mysql> SELECT FROM_UNIXTIME(875996580) + 0;
              -> 19971004222300
      mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
          ->                      '%Y %D %M %h:%i:%s %x');
              -> '2003 6th August 06:22:58 2003'

  Hinweis: Wenn Sie `UNIX_TIMESTAMP()` und `FROM_UNIXTIME()` zur Konvertierung zwischen `TIMESTAMP`-Werten und Unix-Zeitstempelwerten verwenden, ist die Konvertierung verlustbehaftet, weil die Zuordnung nicht in beiden Richtungen 1 : 1 erfolgt. Weitere Informationen entnehmen Sie der Beschreibung der Funktion `UNIX_TIMESTAMP()`.

- `GET_FORMAT(DATE|TIME|DATETIME, 'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL')`

  Gibt einen Format-String zurück. Diese Funktion ist praktisch in Verbindung mit den Funktionen `DATE_FORMAT()` und `STR_TO_DATE()`.

  Die zulässigen Werte für das erste und zweite Argument ergeben verschiedene Möglichkeiten für Format-Strings. (Die Konfigurationsangaben entnehmen Sie der Tabelle in der Beschreibung zu `DATE_FORMAT()`.) Das ISO-Format verweist auf ISO 9075, nicht auf ISO 8601.

  Funktionsaufruf | Ergebnis
  `GET_FORMAT(DATE,'USA')` | `'%m.%d.%Y'`
  `GET_FORMAT(DATE,'JIS')` | `'%Y-%m-%d'`
  `GET_FORMAT(DATE,'ISO')` | `'%Y-%m-%d'`
  `GET_FORMAT(DATE,'EUR')` | `'%d.%m.%Y'`
  `GET_FORMAT(DATE,'INTERNAL')` | `'%Y%m%d'`
  `GET_FORMAT(DATETIME,'USA')` | `'%Y-%m-%d-%H.%i.%s'`
  `GET_FORMAT(DATETIME,'JIS')` | `'%Y-%m-%d %H:%i:%s'`
  `GET_FORMAT(DATETIME,'ISO')` | `'%Y-%m-%d %H:%i:%s'`
  `GET_FORMAT(DATETIME,'EUR')` | `'%Y-%m-%d-%H.%i.%s'`
  `GET_FORMAT(DATETIME,'INTERNAL')` | `'%Y%m%d%H%i%s'`
  `GET_FORMAT(TIME,'USA')` | `'%h:%i:%s %p'`
  `GET_FORMAT(TIME,'JIS')` | `'%H:%i:%s'`
  `GET_FORMAT(TIME,'ISO')` | `'%H:%i:%s'`
  `GET_FORMAT(TIME,'EUR')` | `'%H.%i.%S'`
  `GET_FORMAT(TIME,'INTERNAL')` | `'%H%i%s'`

  `TIMESTAMP` kann auch als erstes Argument für `GET_FORMAT()` verwendet werden. In diesem Fall gibt die Funktion dieselben Werte wie bei `DATETIME` zurück.

      mysql> SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));
              -> '03.10.2003'
      mysql> SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));
              -> '2003-10-31'

- `HOUR(`time`)`

  Gibt die Stundenangabe in `time` zurück. Der Bereich des Rückgabewerts liegt zwischen `0` und `23` bei Tageszeitwerten. Allerdings ist der zulässige Bereich für `TIME` wesentlich größer, d. h., `HOUR` kann Werte zurückgeben, die größer als `23` sind.

      mysql> SELECT HOUR('10:05:03');
              -> 10
      mysql> SELECT HOUR('272:59:59');
              -> 272

- `LAST_DAY(`date`)`

  Nimmt einen `DATE`- oder `DATETIME`-Wert entgegen und gibt den entsprechenden Wert des letzten Tages des betreffenden Monats zurück. Gibt `NULL` zurück, wenn das Argument unzulässig ist.

      mysql> SELECT LAST_DAY('2003-02-05');
              -> '2003-02-28'
      mysql> SELECT LAST_DAY('2004-02-05');
              -> '2004-02-29'
      mysql> SELECT LAST_DAY('2004-01-01 01:01:01');
              -> '2004-01-31'
      mysql> SELECT LAST_DAY('2003-03-32');
              -> NULL

- `LOCALTIME`, `LOCALTIME()`

  `LOCALTIME` und `LOCALTIME()` sind Synonyme von `NOW()`.

- `LOCALTIMESTAMP`, `LOCALTIMESTAMP()`

  `LOCALTIMESTAMP` und `LOCALTIMESTAMP()` sind Synonyme von `NOW()`.

- `MAKEDATE(`year`,`dayofyear`)`

  Gibt ein Datum zurück, welches auf den übergebenen Werten für das Jahr und den Tag im Jahr basiert. `dayofyear` muss größer als 0 sein, andernfalls ist das Ergebnis `NULL`.

      mysql> SELECT MAKEDATE(2001,31), MAKEDATE(2001,32);
              -> '2001-01-31', '2001-02-01'
      mysql> SELECT MAKEDATE(2001,365), MAKEDATE(2004,365);
              -> '2001-12-31', '2004-12-30'
      mysql> SELECT MAKEDATE(2001,0);
              -> NULL

- `MAKETIME(`hour`,`minute`,`second`)`

  Gibt einen Zeitwert zurück, der aus den Argumenten `hour`, `minute` und `second` berechnet wird.

      mysql> SELECT MAKETIME(12,15,30);
              -> '12:15:30'

- `MICROSECOND(`expr`)`

  Gibt die Anzahl der Mikrosekunden für den übergebenen `TIME`- oder `DATETIME`-Ausdruck `expr` als Zahl im Bereich zwischen `0` und `999999` zurück.

      mysql> SELECT MICROSECOND('12:00:00.123456');
              -> 123456
      mysql> SELECT MICROSECOND('1997-12-31 23:59:59.000010');
              -> 10

- `MINUTE(`time`)`

  Gibt die Minute für `time` im Bereich zwischen `0` und `59` zurück.

      mysql> SELECT MINUTE('98-02-03 10:05:03');
              -> 5

- `MONTH(`date`)`

  Gibt den Monat für `date` im Bereich zwischen `0` und `12` zurück.

      mysql> SELECT MONTH('1998-02-03');
              -> 2

- `MONTHNAME(`date`)`

  Gibt den vollständigen Namen des Monats für `date` zurück.

      mysql> SELECT MONTHNAME('1998-02-05');
              -> 'February'

- `NOW()`

  Gibt die aktuellen Werte für Datum und Uhrzeit als Wert in den Formaten `YYYYMMDDHHMMSS` oder `'YYYY-MM-DD HH:MM:SS'` aus. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird.

      mysql> SELECT NOW();
              -> '1997-12-15 23:50:26'
      mysql> SELECT NOW() + 0;
              -> 19971215235026

  Aus einer gespeicherten Routine oder einem Trigger heraus gibt `NOW()` einen Zeitpunkt als Konstante zurück, zu dem die Ausführung der Routine bzw. des Triggers begann. Hier liegt ein Unterschied zum Verhalten von `SYSDATE()` vor, welches die exakte Zeit seiner Ausführung zurückgibt.

- `PERIOD_ADD(`P`,`N`)`

  Fügt `N` Monate zum Zeitraum `P` (im Format `YYMM` oder `YYYYMM`) hinzu. Gibt einen Wert im Format `YYYYMM` zurück. Beachten Sie, dass das Zeitraumargument `P` kein Datumswert ist.

      mysql> SELECT PERIOD_ADD(9801,2);
              -> 199803

- `PERIOD_DIFF(`P1`,`P2`)`

  Gibt die Anzahl der Monate zwischen den Zeiträumen `P1` und `P2` zurück. `P1` und `P2` sollten im Format `YYMM` oder `YYYYMM` übergeben werden. Beachten Sie, dass die Zeitraumargumente `P1` und `P2` keine Datumswerte sind.

      mysql> SELECT PERIOD_DIFF(9802,199703);
              -> 11

- `QUARTER(`date`)`

  Gibt das Quartal im Jahr für `date` zurück. Der Bereich liegt zwischen `1` und `4`.

      mysql> SELECT QUARTER('98-04-01');
              -> 2

- `SECOND(`time`)`

  Gibt die Sekunde für `time` im Bereich zwischen `0` und `59` zurück.

      mysql> SELECT SECOND('10:05:03');
              -> 3

- `SEC_TO_TIME(`seconds`)`

  Gibt das Argument `seconds`, konvertiert in Stunden, Minuten und Sekunden, als Wert in den Formaten `'HH:MM:SS'` oder `HHMMSS` aus. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird.

      mysql> SELECT SEC_TO_TIME(2378);
              -> '00:39:38'
      mysql> SELECT SEC_TO_TIME(2378) + 0;
              -> 3938

- `STR_TO_DATE(`str`,`format`)`

  Dies ist die Umkehrung der Funktion `DATE_FORMAT()`. Sie nimmt einen String `str` und einen Format-String `format` entgegen. `STR_TO_DATE()` gibt einen `DATETIME`-Wert zurück, wenn der Format-String sowohl Datums- als auch Uhrzeitteile enthält, oder einen `DATE`- `TIME`-Wert, wenn der String nur Datums- bzw. Uhrzeitteile umfasst.

  Die `DATE`-, `TIME`- oder `DATETIME`-Werte, die in `str` enthalten sind, sollten in dem Format angegeben werden, das durch `format` spezifiziert wurde. Informationen zu den in `format` verwendbaren Konfigurationsangaben finden Sie in der Beschreibung zur Funktion `DATE_FORMAT()`. Wenn `str` einen unzulässigen `DATE`-, `TIME`- oder `DATETIME`-Wert enthält, gibt `STR_TO_DATE()` `NULL` zurück. Außerdem erzeugt ein unzulässiger Wert eine Warnung.

  Die Bereichsprüfung der Teile von Datumswerten erfolgt wie in Abschnitt 11.3.1, „Die `DATETIME`-, `DATE`- und `TIMESTAMP`-Typen“, beschrieben. Das bedeutet, dass „Nulldaten“ oder solche, bei denen Bestandteile 0 sind, zulässig sind, sofern dem nicht der aktive SQL-Modus widerspricht.

      mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');
              -> '0000-00-00'
      mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
              -> '2004-04-31'

- `SUBDATE(`date`,INTERVAL `expr` `type`)`, `SUBDATE(`expr`,`days`)`

  Wenn mit der Form `INTERVAL` für das zweite Argument aufgerufen wird, ist `SUBDATE()` ein Synonym von `DATE_SUB()`. Weitere Informationen zum Argument `INTERVAL` finden Sie in der Beschreibung zu `DATE_ADD()`.

      mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
              -> '1997-12-02'
      mysql> SELECT SUBDATE('1998-01-02', INTERVAL 31 DAY);
              -> '1997-12-02'

  Die zweite Form gestattet die Verwendung eines Integer-Werts für `days`. In solchen Fällen wird der Wert als Anzahl von Tagen interpretiert, die vom `DATE`- oder `DATETIME`-Ausdruck `expr` abgezogen werden.

      mysql> SELECT SUBDATE('1998-01-02 12:00:00', 31);
              -> '1997-12-02 12:00:00'

  Hinweis: Sie können mit dem Format `"%X%V"` keine Konvertierung eines aus einer Jahres- und einer Wochenangabe bestehenden Strings in ein Datum durchführen, weil diese Kombination nicht eindeutig ein Jahr und einen Monat bezeichnet, wenn eine Woche eine Monatsgrenze überschreitet. Insofern müssen Sie, wenn Sie eine Jahr-/Wochen-Kombination in ein Datum umwandeln wollen, auch den Wochentag angeben:

      mysql> SELECT STR_TO_DATE('200442 Monday', '%X%V %W');
              -> '2004-10-18'

- `SUBTIME(`expr`,`expr2`)`

  `SUBTIME()` zieht `expr2` von `expr` ab und gibt das Ergebnis zurück. `expr` ist eine Uhrzeitangabe oder ein `DATETIME`-Wert, `expr2` eine Uhrzeitangabe.

      mysql> SELECT SUBTIME('1997-12-31 23:59:59.999999','1 1:1:1.000002');
              -> '1997-12-30 22:58:58.999997'
      mysql> SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
              -> '-00:59:59.999999'

- `SYSDATE()`

  Gibt die aktuellen Werte für Datum und Uhrzeit als Wert in den Formaten `YYYYMMDDHHMMSS` oder `'YYYY-MM-DD HH:MM:SS'` aus. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird.

  Aus einer gespeicherten Routine oder einem Trigger heraus gibt `SYSDATE()` die Zeit zurück, zu der sie ausgeführt wird. Dies unterscheidet sich vom Verhalten von `NOW()`, welches die Uhrzeit zurückgibt, zu der die Ausführung der Routine- oder Trigger-Anweisung begann.

- `TIME(`expr`)`

  Extrahiert den Zeitbestandteil des `TIME`- oder `DATETIME`-Ausdrucks `expr` und gibt diesen als String zurück.

      mysql> SELECT TIME('2003-12-31 01:02:03');
              -> '01:02:03'
      mysql> SELECT TIME('2003-12-31 01:02:03.000123');
              -> '01:02:03.000123'

- `TIMEDIFF(`expr`,`expr2`)`

  `TIMEDIFF()` gibt den Zeitraum zwischen der Startzeit `expr` und der Endzeit `expr2` zurück. `expr` und `expr2` sind Zeit- oder `DATETIME`-Ausdrücke, müssen aber vom selben Typ sein.

      mysql> SELECT TIMEDIFF('2000:01:01 00:00:00',
          ->                 '2000:01:01 00:00:00.000001');
              -> '-00:00:00.000001'
      mysql> SELECT TIMEDIFF('1997-12-31 23:59:59.000001',
          ->                 '1997-12-30 01:01:01.000002');
              -> '46:58:57.999999'

- `TIMESTAMP(`expr`)`, `TIMESTAMP(`expr`,`expr2`)`

  Bei nur einem Argument gibt diese Funktion den Datums- oder `DATETIME`-Ausdruck `expr` als `DATETIME`-Wert zurück. Bei zwei Argumenten wird der Zeitausdruck `expr2` zum Datums- oder `DATETIME`-Ausdruck `expr` hinzugefügt und das Ergebnis als `DATETIME`-Wert zurückgegeben.

      mysql> SELECT TIMESTAMP('2003-12-31');
              -> '2003-12-31 00:00:00'
      mysql> SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');
              -> '2004-01-01 00:00:00'

- `TIMESTAMPADD(`interval`,`int_expr`,`datetime_expr`)`

  Fügt den Integer-Ausdruck `int_expr` zum Datums- oder `DATETIME`-Ausdruck `datetime_expr` hinzu. Die Einheit für `int_expr` wird durch das Argument `interval` angegeben, das einen der folgenden Werte haben sollte: `FRAC_SECOND`, `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`, `QUARTER` oder `YEAR`.

  Der `interval`-Wert kann mithilfe eines der angegebenen Schlüsselwörter oder mit dem Präfix `SQL_TSI_` angegeben werden. Beispielsweise sind sowohl `DAY` als auch `SQL_TSI_DAY` zulässig.

      mysql> SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
              -> '2003-01-02 00:01:00'
      mysql> SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');
              -> '2003-01-09'

- `TIMESTAMPDIFF(`interval`,`datetime_expr1`,`datetime_expr2`)`

  Gibt den Unterschied zwischen den Datums- oder `DATETIME`-Ausdrücken `datetime_expr1` und `datetime_expr2` zurück. Die Einheit für das Ergebnis wird über das Argument `interval` angegeben. Die zulässigen Werte für `interval` entsprechen den in der Beschreibung zu `TIMESTAMPADD()` aufgelisteten Optionen.

      mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
              -> 3
      mysql> SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');
              -> -1

- `TIME_FORMAT(`time`,`format`)`

  Wird wie die Funktion `DATE_FORMAT()` verwendet, der String `format` darf aber nur Formatangaben für Stunden, Minuten und Sekunden enthalten. Andere Konfigurationsangaben erzeugen einen `NULL`-Wert oder `0`.

  Wenn der `time`-Wert einen Stundenbestandteil enthält, der größer als `23` ist, erzeugen die Stundenformatangaben `%H` und `%k` einen Wert, der größer ist als der normale Bereich `0 ... 23`. Die übrigen Konfigurationsangaben für das Stundenformat erzeugen den Stundenwert mod 12.

      mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
              -> '100 100 04 04 4'

- `TIME_TO_SEC(`time`)`

  Gibt das Argument `time` in Sekunden konvertiert zurück.

      mysql> SELECT TIME_TO_SEC('22:23:00');
              -> 80580
      mysql> SELECT TIME_TO_SEC('00:39:38');
              -> 2378

- `TO_DAYS(`date`)`

  Gibt zu einem Datum `date` eine Anzahl von Tagen zurück. Diese gibt die Anzahl der seit dem Jahr 0 bis zu diesem Datum verstrichenen Tage zurück.

      mysql> SELECT TO_DAYS(950501);
              -> 728779
      mysql> SELECT TO_DAYS('1997-10-07');
              -> 729669

  `TO_DAYS()` ist nicht für die Verwendung mit Werten geeignet, die vor der Einführung des gregorianischen Kalenders (1582) liegen, da die bei der Kalenderumstellung „verlorenen“ Tage von der Funktion nicht berücksichtigt werden. Bei Daten vor 1582 (und standortabhängig möglicherweise auch danach) sind die Ergebnisse dieser Funktion nicht zuverlässig. Weitere Informationen finden Sie in Abschnitt 12.6, „Welchen Kalender benutzt MySQL?“.

  Denken Sie daran, dass MySQL zweistellige Jahresangaben unter Verwendung der in Abschnitt 11.3, „Datums- und Zeittypen“, beschriebenen Regeln in das vierstellige Format umwandelt. Beispielsweise werden `'1997-10-07'` und `'97-10-07'` als identische Daten betrachtet.

      mysql> SELECT TO_DAYS('1997-10-07'), TO_DAYS('97-10-07');
              -> 729669, 729669

- `UNIX_TIMESTAMP()`, `UNIX_TIMESTAMP(`date`)`

  Sofern ohne Argument aufgerufen, gibt die Funktion einen Unix-Zeitstempel (Sekunden seit `'1970-01-01 00:00:00'` im UTC-Format) als vorzeichenlosen Integer zurück. Wenn `UNIX_TIMESTAMP()` mit einem Argument `date` aufgerufen wird, gibt es den Wert des Arguments als seit dem Zeitpunkt `'1970-01-01 00:00:00'` (UTC) verstrichene Sekunden zurück. `date` kann ein `DATE`-String, ein `DATETIME`-String, ein `TIMESTAMP` oder eine Zahl im Format `YYMMDD` oder `YYYYMMDD` sein. Der Server interpretiert `date` als Wert in der aktuellen Zeitzone und wandelt es in einen internen Wert in UTC um. Clients können ihre Zeitzone wie in Abschnitt 5.11.8, „Zeitzonen-Unterstützung des MySQL-Servers“, beschrieben einstellen.

      mysql> SELECT UNIX_TIMESTAMP();
              -> 882226357
      mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
              -> 875996580

  Wenn `UNIX_TIMESTAMP` für eine `TIMESTAMP`-Spalte verwendet wird, gibt die Funktion den internen Zeitstempelwert direkt zurück, d. h. ohne implizite Konvertierung des Strings in einen Unix-Zeitstempel. Wenn Sie einen Wert außerhalb des zulässigen Bereichs an `UNIX_TIMESTAMP()` übergeben, wird `0` zurückgegeben.

  Hinweis: Wenn Sie `UNIX_TIMESTAMP()` und `FROM_UNIXTIME()` zur Konvertierung zwischen `TIMESTAMP`-Werten und Unix-Zeitstempelwerten verwenden, ist die Konvertierung verlustbehaftet, weil die Zuordnung nicht in beiden Richtungen 1 : 1 erfolgt. Beispielsweise kann es aufgrund der Konventionen zur Änderung der lokalen Zeitzone möglich sein, dass zwei `UNIX_TIMESTAMP()`-Funktionen zwei `TIMESTAMP`-Werte in denselben Unix-Zeitstempelwert umwandeln. `FROM_UNIXTIME()` wiederum konvertiert den Wert dann in nur einen der ursprünglichen `TIMESTAMP`-Werte zurück. Es folgt ein Beispiel unter Verwendung von `TIMESTAMP`-Werten in der Zeitzone `CET` (mitteleuropäische Zeit):

      mysql> SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00');
      +---------------------------------------+
      | UNIX_TIMESTAMP('2005-03-27 03:00:00') |
      +---------------------------------------+
      |                            1111885200 |
      +---------------------------------------+
      mysql> SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00');
      +---------------------------------------+
      | UNIX_TIMESTAMP('2005-03-27 02:00:00') |
      +---------------------------------------+
      |                            1111885200 |
      +---------------------------------------+
      mysql> SELECT FROM_UNIXTIME(1111885200);
      +---------------------------+
      | FROM_UNIXTIME(1111885200) |
      +---------------------------+
      | 2005-03-27 03:00:00       |
      +---------------------------+

  Wenn Sie `UNIX_TIMESTAMP()`-Spalten subtrahieren wollen, sollten Sie das Ergebnis in vorzeichenbehaftete Integers umwandeln. Siehe auch Abschnitt 12.8, „Cast-Funktionen und Operatoren“.

- `UTC_DATE`, `UTC_DATE()`

  Gibt das aktuelle UTC-Datum als Wert in den Formaten `'YYYY-MM-DD'` oder `YYYYMMDD` aus. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird.

      mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
              -> '2003-08-14', 20030814

- `UTC_TIME`, `UTC_TIME()`

  Gibt die aktuelle UTC-Uhrzeit als Wert in den Formaten `'HH:MM:SS'` oder `HHMMSS` aus. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird.

      mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
              -> '18:07:53', 180753

- `UTC_TIMESTAMP`, `UTC_TIMESTAMP()`

  Gibt die aktuellen UTC-Werte für Datum und Uhrzeit als Wert in den Formaten `YYYYMMDDHHMMSS` oder `'YYYY-MM-DD HH:MM:SS'` aus. Das Ausgabeformat hängt davon ab, ob die Funktion in einem String- oder einem numerischen Kontext verwendet wird.

      mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
              -> '2003-08-14 18:08:04', 20030814180804

- `WEEK(`date`[,`mode`])`

  Diese Funktion gibt die Nummer der Woche für `date` zurück. Wird `WEEK()` mit zwei Argumenten verwendet, dann gestattet Ihnen die Funktion die Angabe, ob die Woche am Sonntag oder Montag beginnt und ob der Rückgabewert im Bereich zwischen `0` und `53` oder `1` und `53` liegen soll. Wird das Argument `mode` weggelassen, so wird der Wert der Systemvariablen `default_week_format` verwendet. Siehe auch Abschnitt 5.2.2, „Server-Systemvariablen“.

  Die folgende Tabelle beschreibt, wie das Argument `mode` funktioniert.

  | Erster |  |
  Modus | Wochentag | Bereich | Woche 1 ist die erste Woche …
  0 | Sonntag | 0–53 | mit einem Sonntag in diesem Jahr
  1 | Montag | 0–53 | mit mehr als drei Tagen innerhalb dieses Jahres
  2 | Sonntag | 1–53 | mit einem Sonntag in diesem Jahr
  3 | Montag | 1–53 | mit mehr als drei Tagen innerhalb dieses Jahres
  4 | Sonntag | 0–53 | mit mehr als drei Tagen innerhalb dieses Jahres
  5 | Montag | 0–53 | mit einem Montag in diesem Jahr
  6 | Sonntag | 1–53 | mit mehr als drei Tagen innerhalb dieses Jahres
  7 | Montag | 1–53 | mit einem Montag in diesem Jahr

      mysql> SELECT WEEK('1998-02-20');
              -> 7
      mysql> SELECT WEEK('1998-02-20',0);
              -> 7
      mysql> SELECT WEEK('1998-02-20',1);
              -> 8
      mysql> SELECT WEEK('1998-12-31',1);
              -> 53

  Beachten Sie, dass, wenn ein Datum in die letzte Woche des vorherigen Jahres fällt, MySQL `0` zurückgibt, sofern Sie nicht `2`, `3`, `6` oder `7` als optionales `mode`-Argument angeben:

      mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
              -> 2000, 0

  Man könnte nun anführen, dass MySQL doch eigentlich `52` für die Funktion `WEEK()` zurückgeben sollte, da das angegebene Datum eigentlich in der 52. Woche des Jahres 1999 liegt. Wir haben aber beschlossen, stattdessen `0` zurückgeben zu lassen, weil die Funktion „Nummer der Woche im angegebenen Jahr“ zurückgeben soll. Dies macht die Verwendung der Funktion `WEEK()` zuverlässig, wenn sie mit anderen Funktionen kombiniert wird, die einen Tagesbestandteil aus dem Datum extrahieren.

  Wenn Sie eine Auswertung des Ergebnisses in Bezug auf das Jahr vorziehen, das den ersten Tag der Woche des angegebenen Datums enthält, dann verwenden Sie `0`, `2`, `5` oder `7` als optionales `mode`-Argument.

      mysql> SELECT WEEK('2000-01-01',2);
              -> 52

  Alternativ verwenden Sie die Funktion `YEARWEEK()`:

      mysql> SELECT YEARWEEK('2000-01-01');
              -> 199952
      mysql> SELECT MID(YEARWEEK('2000-01-01'),5,2);
              -> '52'

- `WEEKDAY(`date`)`

  Gibt den Wochentagindex für `date` zurück (`0` = Montag, `1` = Dienstag, …, `6` = Sonntag).

      mysql> SELECT WEEKDAY('1998-02-03 22:23:00');
              -> 1
      mysql> SELECT WEEKDAY('1997-11-05');
              -> 2

- `WEEKOFYEAR(`date`)`

  Gibt die Kalenderwoche des Datums als Zahl im Bereich zwischen `1` und `53` zurück. `WEEKOFYEAR()` ist eine Kompatibilitätsfunktion, die äquivalent zu `WEEK(`date`,3)` ist.

      mysql> SELECT WEEKOFYEAR('1998-02-20');
              -> 8

- `YEAR(`date`)`

  Gibt das Jahr für `date` im Bereich zwischen `1000` und `9999` oder aber `0` für das „Nulldatum“ zurück.

      mysql> SELECT YEAR('98-02-03');
              -> 1998

- `YEARWEEK(`date`)`, `YEARWEEK(`date`,`start`)`

  Gibt Jahr und Woche für ein Datum zurück. Das Argument `start` funktioniert ganz genauso wie das Argument `start` für `WEEK()`. Das Jahr im Ergebnis kann sich im Falle der ersten und der letzten Woche des Jahres vom Jahr im Datumsargument unterscheiden.

      mysql> SELECT YEARWEEK('1987-01-01');
              -> 198653

  Beachten Sie, dass die Wochennummer sich von dem, was die Funktion `WEEK()` für ihre optionalen Argumente `0` oder `1` zurückgäbe (nämlich `0`), unterscheidet, denn `WEEK()` gibt die Woche im Kontext des angegebenen Jahres zurück.

## 12.6. Welchen Kalender benutzt MySQL?

MySQL verwendet den so genannten proleptischen gregorianischen Kalender.

Jedes Land, das die Zeitrechnung vom julianischen auf den gregorianischen Kalender umgestellt hat, hat bei dieser Umstellung mindestens zehn Tage verloren. Um zu verstehen, wie dies funktioniert, betrachten Sie den Oktober 1582, als die erste Umstellung vom julianischen auf den gregorianischen Kalender erfolgte:

Montag | Dienstag | Mittwoch | Donnerstag | Freitag | Sonnabend | Sonntag
1 | 2 | 3 | 4 | 15 | 16 | 17
18 | 19 | 20 | 21 | 22 | 23 | 24
25 | 26 | 27 | 28 | 29 | 30 | 31

Zwischen dem 4. und dem 15. Oktober liegen keine Daten. Diese Unstetigkeit nennt man Ausschaltung. Alle Daten vor der Ausschaltung waren julianisch, alle nachfolgenden gregorianisch. Die Daten während der Ausschaltung existieren schlichtweg nicht.

Ein Kalender, der für Daten angewendet wird, zu deren Zeit er (noch) nicht verwendet wurde, heißt proleptisch. Auf diese Weise haben wir, wenn wir voraussetzen, dass niemals eine Ausschaltung stattgefunden hat und die Regeln des gregorianischen Kalenders immer gegolten haben, einen proleptischen gregorianischen Kalender. Diesen verwenden wir entsprechend der Vorgabe von SQL auch bei MySQL. Aus diesem Grund müssen vor der Ausschaltung liegende Daten, die als `DATE`- oder `DATETIME`-Werte in MySQL gespeichert werden, angepasst werden, um den Unterschied auszugleichen. Wichtig ist in diesem Zusammenhang die Tatsache, dass die Ausschaltung nicht in allen Ländern gleichzeitig erfolgte und dass umso mehr Tage verloren gingen, je später sie erfolgte. In Großbritannien beispielsweise fand sie 1752 statt, als auf Mittwoch, den 2. September, Donnerstag, der 14. September, folgte. Russland behielt den julianischen Kalender bis 1918 bei und verlor bei der Umstellung 13 Tage – was auch bedeutet, dass die berühmte Oktoberrevolution eigentlich im November stattfand.

## 12.7. MySQL-Volltextsuche

- `MATCH (`col1`,`col2`,...) AGAINST (`expr` [IN BOOLEAN MODE | WITH QUERY EXPANSION])`

  MySQL unterstützt die Volltextindizierung und -suche. Ein Volltextindex ist in MySQL ein Index des Typs `FULLTEXT`. `FULLTEXT`-Indizes können nur bei `MyISAM`-Tabellen eingesetzt werden. Sie lassen sich für `CHAR`-, `VARCHAR`- und `TEXT`-Spalten mit `CREATE TABLE` erstellen oder mit `ALTER TABLE` oder `CREATE INDEX` im Nachhinein hinzufügen. Bei größeren Datenmengen erfolgt das Laden Ihrer Daten in eine Tabelle ohne `FULLTEXT`-Index und das nachfolgende Erstellen des Indexes wesentlich schneller als das Einladen in eine Tabelle mit vorhandenem `FULLTEXT`-Index.

  Hinweise zu Einschränkungen bei der Volltextsuche finden Sie in Abschnitt 12.7.4, „Beschränkungen der Volltextsuche“.

Die Volltextsuche wird mit der Funktion `MATCH()` ausgeführt.

    mysql> CREATE TABLE articles (
        ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
        ->   title VARCHAR(200),
        ->   body TEXT,
        ->   FULLTEXT (title,body)
        -> );
    Query OK, 0 rows affected (0.00 sec)

    mysql> INSERT INTO articles (title,body) VALUES
        -> ('MySQL Tutorial','DBMS stands for DataBase ...'),
        -> ('How To Use MySQL Well','After you went through a ...'),
        -> ('Optimizing MySQL','In this tutorial we will show ...'),
        -> ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
        -> ('MySQL vs. YourSQL','In the following database comparison ...'),
        -> ('MySQL Security','When configured properly, MySQL ...');
    Query OK, 6 rows affected (0.00 sec)
    Records: 6  Duplicates: 0  Warnings: 0

    mysql> SELECT * FROM articles
        -> WHERE MATCH (title,body) AGAINST ('database');
    +----+-------------------+------------------------------------------+
    | id | title             | body                                     |
    +----+-------------------+------------------------------------------+
    |  5 | MySQL vs. YourSQL | In the following database comparison ... |
    |  1 | MySQL Tutorial    | DBMS stands for DataBase ...             |
    +----+-------------------+------------------------------------------+
    2 rows in set (0.00 sec)

Die Funktion `MATCH()` führt eine natursprachliche Suche nach einem String in einer Textsammlung durch. Eine Sammlung ist eine Menge von einer oder mehreren Spalten, die Bestandteil eines `FULLTEXT`-Indexes sind. Der Such-String wird als Argument an `AGAINST()` übergeben. Für jeden Datensatz in der Tabelle gibt `MATCH()` einen Relevanzwert zurück, d. h. eine Maßangabe für die Ähnlichkeit zwischen dem Such-String und dem Text in den in `MATCH()` aufgelisteten Spalten dieses Datensatzes.

Standardmäßig wird die Suche ohne Unterscheidung der Groß-/Kleinschreibung durchgeführt. Sie können jedoch auch eine Suche unter Berücksichtigung der Groß-/Kleinschreibung durchführen, indem Sie eine binäre Sortierung für die indizierten Spalten verwenden. So können Sie etwa einer Spalte, die den Zeichensatz `latin1` verwendet, die Sortierung `latin1_bin` zuweisen, damit bei der Volltextsuche die Groß-/Kleinschreibung unterschieden wird.

Wenn `MATCH()` in einer `WHERE`-Klausel verwendet wird (vgl. obiges Beispiel), dann werden die zurückgegebenen Datensätze automatisch nach absteigender Relevanz sortiert. Relevanzwerte sind nichtnegative Fließkommazahlen. Nullrelevanz bezeichnet keinerlei Ähnlichkeit. Die Relevanz wird auf der Basis der Anzahl der Wörter im Datensatz, der Anzahl eindeutiger Wörter im Datensatz, der Gesamtanzahl der Wörter in der Sammlung und der Anzahl der Dokumente (Datensätze) berechnet, die ein bestimmtes Wort enthalten.

Bei der natursprachlichen Volltextsuche ist es erforderlich, dass die in der `MATCH()`-Funktion genannten Spalten dieselben Spalten sind, die in einem in Ihrer Tabelle vorhandenen `FULLTEXT`-Index enthalten sind. Beachten Sie bei der obigen Abfrage, dass die in der `MATCH()`-Funktion aufgeführten Spalten (`title` und `body`) dieselben sind, die in der Definition des `FULLTEXT`-Indexes der Tabelle `article` genannt sind. Sollten Sie nun `title` oder `body` separat durchsuchen wollen, dann müssten Sie für jede Spalte separate `FULLTEXT`-Indizes erstellen.

Es ist auch möglich, eine boolesche Suche oder eine Suche mit Abfrageerweiterung durchzuführen. Diese Suchtypen sind in Abschnitt 12.7.1, „Boolesche Volltextsuche“, und Abschnitt 12.7.2, „Volltextsuche mit Abfragenerweiterung“, beschrieben.

Das obige Beispiel ist eine einfache Veranschaulichung, die zeigt, wie man die Funktion `MATCH()` verwendet, wobei Datensätze nach absteigender Relevanz sortiert zurückgegeben werden. Das nächste Beispiel zeigt, wie man die Relevanzwerte explizit abruft. Zurückgegebene Datensätze werden nicht sortiert, weil die `SELECT`-Anweisung weder eine `WHERE`- noch eine `ORDER BY`-Klausel enthält:

    mysql> SELECT id, MATCH (title,body) AGAINST ('Tutorial')
        -> FROM articles;
    +----+-----------------------------------------+
    | id | MATCH (title,body) AGAINST ('Tutorial') |
    +----+-----------------------------------------+
    |  1 |                        0.65545833110809 |
    |  2 |                                       0 |
    |  3 |                        0.66266459226608 |
    |  4 |                                       0 |
    |  5 |                                       0 |
    |  6 |                                       0 |
    +----+-----------------------------------------+
    6 rows in set (0.00 sec)

Das folgende Beispiel ist komplexer. Die Abfrage gibt die Relevanzwerte zurück und sortiert die Datensätze zudem nach absteigender Relevanz. Um dieses Ergebnis zu erhalten, sollten Sie `MATCH()` zweimal angeben: einmal in der `SELECT`-Liste und ein weiteres Mal in der `WHERE`-Klausel. Hierdurch wird die Systembelastung nicht erhöht, da der MySQL-Optimierer bemerkt, dass die beiden `MATCH()`-Aufrufe identisch sind, und den Code für die Volltextsuche insofern nur einmal aufruft.

    mysql> SELECT id, body, MATCH (title,body) AGAINST
        -> ('Security implications of running MySQL as root') AS score
        -> FROM articles WHERE MATCH (title,body) AGAINST
        -> ('Security implications of running MySQL as root');
    +----+-------------------------------------+-----------------+
    | id | body                                | score           |
    +----+-------------------------------------+-----------------+
    |  4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 |
    |  6 | When configured properly, MySQL ... | 1.3114095926285 |
    +----+-------------------------------------+-----------------+
    2 rows in set (0.00 sec)

Die `FULLTEXT`-Implementierung von MySQL betrachtet alle Folgen echter Wortzeichen (Buchstaben, Ziffern und Unterstriche) als Wort. Die Folge kann auch Apostrophe (`'`) enthalten, aber nur eines je Datensatz. Das bedeutet, dass `aaa'bbb` als ein Wort betrachtet wird, `aaa''bbb` hingegen als zwei Wörter. Apostrophe am Anfang oder Ende eines Wortes werden vom `FULLTEXT`-Parser entfernt, d. h., er verarbeitet `'aaa'bbb'` als `aaa'bbb`.

Der `FULLTEXT`-Parser bestimmt anhand bestimmter Trennzeichen wie ‘`` ’ (Leerzeichen), ‘`,`’ (Komma), und ‘`.`’ (Punkt), wo Wörter anfangen und enden. Wenn Wörter nicht durch Trennzeichen getrennt werden (wie es beispielsweise im Chinesischen der Fall ist), kann der `FULLTEXT`-Parser nicht ermitteln, wo ein Wort beginnt oder endet. Damit Wörter oder andere indizierte Begriffe in solchen Sprachen einem `FULLTEXT`-Index hinzugefügt werden können, müssen Sie eine Vorabverarbeitung durchführen und sie so durch ein beliebiges Trennzeichen (z. B. ‘`"`’) voneinander abtrennen.

In MySQL 5.1 ist es möglich, ein Plug-In zu schreiben, das den integrierten Volltext-Parser ersetzt. Detaillierte Informationen finden Sie in Abschnitt 26.2, „Die MySQL-Plug-In-Schnittstelle“. Ein Beispiel für den Quellcode eines solchen Parser-Plug-Ins finden Sie im Verzeichnis `plugin/fulltext` einer MySQL-Quelldistribution.

Einige Wörter werden bei der Volltextsuche ignoriert:

- Ignoriert werden alle Wörter, die zu kurz sind. Die standardmäßige Mindestlänge von Wörtern, die von der Volltextsuche gefunden werden, beträgt vier Zeichen.

- Auch Wörter, die auf der Liste der Stoppwörter stehen, werden ignoriert. Ein Stoppwort ist ein Wort wie „the“ oder „some“, das so verbreitet ist, dass sein semantischer Wert als vernachlässigbar betrachtet wird. Es gibt eine bereits vorhandene Liste mit Stoppwörtern, die aber mit einer benutzerdefinierten Liste überschrieben werden kann.

Die Standardliste mit den Stoppwörtern finden Sie in Abschnitt 12.7.3, „Stoppwörter in der Volltextsuche“. Mindestwortlänge und Stoppwortliste lassen sich wie in Abschnitt 12.7.5, „MySQL-Volltextsuche feineinstellen“, beschrieben ändern.

Jedes korrekte Wort in der Sammlung und in der Abfrage wird entsprechend seiner Bedeutung in der Sammlung oder Abfrage gewichtet. Hieraus ergibt sich, dass ein Wort, dass in vielen Dokumenten vorhanden ist, ein niedrigeres Gewicht (oder sogar ein Nullgewicht) hat, weil sein semantischer Wert in dieser speziellen Sammlung geringer ist. Umgekehrt erhält ein Wort, das selten vorkommt, ein höheres Gewicht. Die Gewichtungen der Wörter werden zusammengefasst, und auf dieser Basis wird die Relevanz des Datensatzes berechnet.

Eine solche Methode funktioniert am besten mit großen Sammlungen (und sie wurde auch speziell auf diesen Zweck hin sorgfältig optimiert). Bei sehr kleinen Tabellen spiegelt die Wortverteilung ihren jeweiligen semantischen Wert nicht adäquat wider. So ist etwa das Wort „MySQL“ in jedem Datensatz der oben gezeigten Tabelle `articles` vorhanden, d. h., eine Suche nach diesem Wort führt zu keinem Ergebnis:

    mysql> SELECT * FROM articles
        -> WHERE MATCH (title,body) AGAINST ('MySQL');
    Empty set (0.00 sec)

Das Suchergebnis ist leer, weil das Wort „MySQL“ in mindestens 50 Prozent der Datensätze vorhanden ist. Insofern wird es letztendlich als Stoppwort behandelt. Bei großen Datenmengen ist dieses Verhalten wünschenswert: Eine natursprachliche Abfrage sollte keinesfalls jeden zweiten Datensatz aus einer 1 Gbyte großen Tabelle zurückgeben. Bei kleinen Datenmengen hingegen ist der Ansatz nicht sehr praktisch.

Ein Wort, das in der Hälfte der Datensätze in einer Tabelle auftritt, scheint wenig geeignet, relevante Dokumente zu finden. Tatsächlich werden in einem solchen Fall viele irrelevante Dokumente gefunden. Wie wir alle wissen, passiert dies viel zu häufig, etwa wenn wir versuchen, mit einer Suchmaschine etwas im Internet zu finden. Hieraus ist zu schließen, dass Datensätzen, die das Wort enthalten, ein niedriger semantischer Wert für die spezielle Datenmenge, in der sie auftreten, zugewiesen wird. Denn ein Wort kann die 50-Prozent-Marke in einer Datenmenge überschreiten, in einer anderen jedoch nicht.

Diese Marke hat eine große Bedeutung, wenn Sie die Volltextsuche zum ersten Mal ausprobieren, um zu sehen, wie sie funktioniert: Wenn Sie eine Tabelle erstellen und nur einen oder zwei Datensätze mit Text einfügen, tritt jedes Wort im Text in mindestens 50 Prozent aller Datensätze auf. Die Suche gibt also in keinem Fall Ergebnisse zurück. Sie sollten also mindestens drei (und am besten noch mehr) Datensätze einfügen. Benutzer, die die 50-Prozent-Grenze umgehen wollen, können den booleschen Suchmodus verwenden. Siehe auch Abschnitt 12.7.1, „Boolesche Volltextsuche“.

### 12.7.1. Boolesche Volltextsuche

MySQL kann eine boolesche Volltextsuche unter Verwendung des Modifizierers `IN BOOLEAN MODE` durchführen:

    mysql> SELECT * FROM articles WHERE MATCH (title,body)
        -> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
    +----+-----------------------+-------------------------------------+
    | id | title                 | body                                |
    +----+-----------------------+-------------------------------------+
    |  1 | MySQL Tutorial        | DBMS stands for DataBase ...        |
    |  2 | How To Use MySQL Well | After you went through a ...        |
    |  3 | Optimizing MySQL      | In this tutorial we will show ...   |
    |  4 | 1001 MySQL Tricks     | 1. Never run mysqld as root. 2. ... |
    |  6 | MySQL Security        | When configured properly, MySQL ... |
    +----+-----------------------+-------------------------------------+

Die Operatoren `+` und `-` geben an, dass ein Wort vorhanden sein muss bzw. nicht sein darf, damit eine Übereinstimmung vorliegt. Insofern ruft diese Abfrage alle Datensätze ab, die das Wort „MySQL“, aber nicht das Wort „YourSQL“ enthalten.

Die boolesche Volltextsuche hat die folgenden Merkmale:

- Sie verwendet die 50-Prozent-Marke nicht.

- Datensätze werden nicht automatisch nach absteigender Relevanz sortiert. Dies erkennen Sie am obigen Abfrageergebnis: Der Datensatz mit der höchsten Relevanz ist derjenige, der „MySQL“ zweimal enthält. Er wird aber nicht als Erster, sondern als Letzter aufgeführt.

- Sie funktioniert auch ohne `FULLTEXT`-Index, auch wenn eine derart ausgeführte Suche recht lange dauert.

- Die Volltextparameter für minimale und maximale Wortlängen werden angewendet.

- Die Stoppwortliste wird angewendet.

Die boolesche Volltextsuche unterstützt die folgenden Operatoren:

- `+`

  Ein führendes Pluszeichen gibt an, dass das betreffende Wort in jedem zurückgegebenen Datensatz vorhanden sein muss.

- `-`

  Ein führendes Minuszeichen gibt an, dass dieses Wort nicht in einem Datensatz vorhanden sein darf, der zurückgegeben wird.

  Hinweis: Der Operator `-` schließt nur solche Datensätze aus, die andernfalls Bestandteil des Ergebnisses wären. Aufgrund dessen gibt eine boolesche Suche, die nur mit Minuszeichen gekennzeichnete Begriffe enthält, ein leeres Ergebnis zurück, nicht jedoch „alle Datensätze mit Ausnahme derer, die einen der ausgeschlossenen Begriffe enthalten“.

- (kein Operator)

  Standardmäßig (also wenn weder `+` noch `-` angegeben sind) ist das Wort optional, aber Datensätze, die es enthalten, werden weiter oben einsortiert. Dies ahmt das Verhalten von `MATCH() ... AGAINST()` ohne den Modifizierer `IN BOOLEAN MODE` nach.

- `> <`

  Diese beiden Operatoren werden verwendet, um den Anteil eines Worts am Relevanzwert zu ändern, der einem Datensatz zugewiesen wird. Der Operator `>` erhöht den Anteil, der Operator `<` verringert ihn. Ein Beispiel finden Sie nach dieser Liste.

- `( )`

  Mit Klammern werden Wörter zu Unterausdrücken zusammengefasst. Gruppen in Klammern können verschachtelt werden.

- `~`

  Eine führende Tilde fungiert als Negationsoperator, d. h., der Anteil des Wortes an der Relevanz des Datensatzes wird negativ gewertet. Dies ist nützlich, um „Störungswörter“ zu kennzeichnen. Ein Datensatz, der ein solches Wort enthält, erhält eine geringere Relevanz als andere, wird aber – anders als bei `-` – nicht vollständig aus dem Ergebnis ausgeschlossen.

- `*`

  Das Sternchen dient als Kürzungs- oder Jokeroperator. Anders als andere Operatoren wird es an das betreffende Wort angehängt. Eine Übereinstimmung liegt bei Wörtern vor, die mit dem vor dem Operator `*` stehenden Wort beginnen.

- `"`

  Eine Phrase, die in doppelte Anführungszeichen (‘`"`’) gesetzt ist, entspricht nur solchen Datensätzen, in denen diese Phrase wortwörtlich (d. h. wie eingegeben) vorkommt. Die Volltextsuche unterteilt die Phrase in Wörter und führt dann eine Suche nach ihnen im `FULLTEXT`-Index durch. Bei Zeichen, die nicht zum Wort gehören, muss keine exakte Übereinstimmung vorliegen: Die Phrasensuche erfordert lediglich, dass bei passenden Datensätzen dieselben Wörter in genau der in der Phrase angegebenen Reihenfolge vorhanden sind. So entspricht beispielsweise `"test phrase"` `"test, phrase"`.

  Wenn die Phrase keine Wörter enthält, die im Index vorhanden sind, ist das Ergebnis leer. Wenn beispielsweise alle Wörter Stoppwörter oder kürzer sind als die Mindestlänge für indizierte Wörter, dann ist das Ergebnis leer.

Die folgenden Beispiele veranschaulichen einige Such-Strings, die boolesche Volltextoperatoren verwenden:

- `'apple banana'`

  Findet Datensätze, die mindestens eines der beiden Wörter enthalten.

- `'+apple +juice'`

  Findet Datensätze, die beide Wörter enthalten.

- `'+apple macintosh'`

  Findet Datensätze, die das Wort „apple“ enthalten, stuft aber solche Datensätze höher ein, die auch „macintosh“ enthalten.

- `'+apple -macintosh'`

  Findet Datensätze, die das Wort „apple“, aber nicht das Wort „macintosh“ enthalten.

- `'+apple ~macintosh'`

  Findet Datensätze, die das Wort „apple“ enthalten. Datensätze, die außerdem das Wort „macintosh“ enthalten, werden niedriger eingestuft als solche, die es nicht enthalten. Dies ist „sanfter“ als eine Suche nach `'+apple -macintosh'`, bei der ein Datensatz bei Vorhandensein von „macintosh“ überhaupt nicht zurückgegeben wird.

- `'+apple +(>turnover <strudel)'`

  Findet Datensätze, die die Wörter „apple“ und „turnover“ oder „apple“ und „strudel“ (in beliebiger Reihenfolge) enthalten, aber stuft „apple turnover“ höher ein als „apple strudel“.

- `'apple*'`

  Findet Datensätze, die Wörter wie „apple“, „apples“, „applesauce“ oder „applet“ enthalten.

- `'"some words"'`

  Findet Datensätze, die die exakte Phrase „some words“ enthalten. Dies wäre etwa „some words of wisdom“, nicht aber „some noise words“. Beachten Sie, dass die ‘`"`’-Anführungszeichen, die die Phrase umschließen, Operatorzeichen sind, die der Trennung der Phrase dienen. Es handelt sich hierbei nicht um Anführungszeichen, die den Such-String selbst umfassen.

### 12.7.2. Volltextsuche mit Abfragenerweiterung

Die Volltextsuche unterstützt die Abfrageerweiterung (und insbesondere die Variante „blinde Abfrageerweiterung“). Dies ist in der Regel nützlich, wenn eine Suchphrase zu kurz ist, was oft bedeutet, dass der Benutzer auf implizites Wissen angewiesen ist, welches der Volltextsuch-Engine fehlt. So weiß ein Benutzer, der nach dem Begriff „database“ sucht, normalerweise, dass „MySQL“, „Oracle“, „DB2“ und „RDBMS“ Phrasen sind, die „database“ entsprechen und insofern ebenfalls zurückgegeben werden sollten. Dies nennt man implizites Wissen.

Die blinde Abfrageerweiterung (auch „automatisches Relevanzfeedback“ genannt) wird durch Anhängen von `WITH QUERY EXPANSION` an die Suchphrase aktiviert. Sie funktioniert, indem die Suche zweimal durchgeführt wird, wobei die Suchphrase für die zweite Suche der ursprünglichen Suchphrase entspricht, die mit einigen wenigen Dokumenten aus der ersten Suche verkettet wurde. Wenn also eines der Dokumente das Wort „database“ und das Wort „MySQL“ enthält, findet die zweite Suche Dokumente, die das Wort „MySQL“ enthalten – und zwar auch dann, wenn „database“ gar nicht enthalten ist. Das folgende Beispiel veranschaulicht diesen Unterschied:

    mysql> SELECT * FROM articles
        -> WHERE MATCH (title,body) AGAINST ('database');
    +----+-------------------+------------------------------------------+
    | id | title             | body                                     |
    +----+-------------------+------------------------------------------+
    |  5 | MySQL vs. YourSQL | In the following database comparison ... |
    |  1 | MySQL Tutorial    | DBMS stands for DataBase ...             |
    +----+-------------------+------------------------------------------+
    2 rows in set (0.00 sec)

    mysql> SELECT * FROM articles
        -> WHERE MATCH (title,body)
        -> AGAINST ('database' WITH QUERY EXPANSION);
    +----+-------------------+------------------------------------------+
    | id | title             | body                                     |
    +----+-------------------+------------------------------------------+
    |  1 | MySQL Tutorial    | DBMS stands for DataBase ...             |
    |  5 | MySQL vs. YourSQL | In the following database comparison ... |
    |  3 | Optimizing MySQL  | In this tutorial we will show ...        |
    +----+-------------------+------------------------------------------+
    3 rows in set (0.00 sec)

Ein weiteres Beispiel könnte die Suche nach den Maigret-Büchern von Georges Simenon sein, wobei der Benutzer nicht genau weiß, wie sich „Maigret“ schreibt. Eine Suche nach „Megre and the reluctant witnesses“ findet ohne Abfrageerweiterung nur „Maigret and the Reluctant Witnesses“. Eine Suche mit Abfrageerweiterung findet im zweiten Durchlauf alle Bücher mit dem Wort „Maigret“.

Hinweis: Da die blinde Abfrageerweiterung sehr viele irrelevante Dokumente zurückgibt, ist sie nur sinnvoll, wenn die Suchphrase sehr kurz ist.

### 12.7.3. Stoppwörter in der Volltextsuche

Die folgende Tabelle zeigt die Standardliste der Stoppwörter für die Volltextsuche. Die Stoppwörter sind englisch. Eine Lokalisierung, zum Beispiel die Übersetzung in die deutsche Sprache, ist derzeit noch nicht vorgesehen. (Die Stoppwörter sind im Quellcode hardkodiert.)

a's | able | about | above | according
accordingly | across | actually | after | afterwards
again | against | ain't | all | allow
allows | almost | alone | along | already
also | although | always | am | among
amongst | an | and | another | any
anybody | anyhow | anyone | anything | anyway
anyways | anywhere | apart | appear | appreciate
appropriate | are | aren't | around | as
aside | ask | asking | associated | at
available | away | awfully | be | became
because | become | becomes | becoming | been
before | beforehand | behind | being | believe
below | beside | besides | best | better
between | beyond | both | brief | but
by | c'mon | c's | came | can
can't | cannot | cant | cause | causes
certain | certainly | changes | clearly | co
com | come | comes | concerning | consequently
consider | considering | contain | containing | contains
corresponding | could | couldn't | course | currently
definitely | described | despite | did | didn't
different | do | does | doesn't | doing
don't | done | down | downwards | during
each | edu | eg | eight | either
else | elsewhere | enough | entirely | especially
et | etc | even | ever | every
everybody | everyone | everything | everywhere | ex
exactly | example | except | far | few
fifth | first | five | followed | following
follows | for | former | formerly | forth
four | from | further | furthermore | get
gets | getting | given | gives | go
goes | going | gone | got | gotten
greetings | had | hadn't | happens | hardly
has | hasn't | have | haven't | having
he | he's | hello | help | hence
her | here | here's | hereafter | hereby
herein | hereupon | hers | herself | hi
him | himself | his | hither | hopefully
how | howbeit | however | i'd | i'll
i'm | i've | ie | if | ignored
immediate | in | inasmuch | inc | indeed
indicate | indicated | indicates | inner | insofar
instead | into | inward | is | isn't
it | it'd | it'll | it's | its
itself | just | keep | keeps | kept
know | knows | known | last | lately
later | latter | latterly | least | less
lest | let | let's | like | liked
likely | little | look | looking | looks
ltd | mainly | many | may | maybe
me | mean | meanwhile | merely | might
more | moreover | most | mostly | much
must | my | myself | name | namely
nd | near | nearly | necessary | need
needs | neither | never | nevertheless | new
next | nine | no | nobody | non
none | noone | nor | normally | not
nothing | novel | now | nowhere | obviously
of | off | often | oh | ok
okay | old | on | once | one
ones | only | onto | or | other
others | otherwise | ought | our | ours
ourselves | out | outside | over | overall
own | particular | particularly | per | perhaps
placed | please | plus | possible | presumably
probably | provides | que | quite | qv
rather | rd | re | really | reasonably
regarding | regardless | regards | relatively | respectively
right | said | same | saw | say
saying | says | second | secondly | see
seeing | seem | seemed | seeming | seems
seen | self | selves | sensible | sent
serious | seriously | seven | several | shall
she | should | shouldn't | since | six
so | some | somebody | somehow | someone
something | sometime | sometimes | somewhat | somewhere
soon | sorry | specified | specify | specifying
still | sub | such | sup | sure
t's | take | taken | tell | tends
th | than | thank | thanks | thanx
that | that's | thats | the | their
theirs | them | themselves | then | thence
there | there's | thereafter | thereby | therefore
therein | theres | thereupon | these | they
they'd | they'll | they're | they've | think
third | this | thorough | thoroughly | those
though | three | through | throughout | thru
thus | to | together | too | took
toward | towards | tried | tries | truly
try | trying | twice | two | un
under | unfortunately | unless | unlikely | until
unto | up | upon | us | use
used | useful | uses | using | usually
value | various | very | via | viz
vs | want | wants | was | wasn't
way | we | we'd | we'll | we're
we've | welcome | well | went | were
weren't | what | what's | whatever | when
whence | whenever | where | where's | whereafter
whereas | whereby | wherein | whereupon | wherever
whether | which | while | whither | who
who's | whoever | whole | whom | whose
why | will | willing | wish | with
within | without | won't | wonder | would
would | wouldn't | yes | yet | you
you'd | you'll | you're | you've | your
yours | yourself | yourselves | zero |

### 12.7.4. Beschränkungen der Volltextsuche

- Die Volltextsuche wird nur für `MyISAM`-Tabellen unterstützt.

- Sie kann mit den meisten Multibytezeichensätzen benutzt werden. Eine Ausnahme ist Unicode: Der Zeichensatz `utf8` kann verwendet werden, nicht aber der Zeichensatz `ucs2`.

- Ideografische Sprachen wie das Chinesische und das Japanische kennen keine Worttrennzeichen. Aus diesem Grund kann der `FULLTEXT`-Parser bei diesen und anderen Sprachen nicht bestimmen, wo ein Wort anfängt oder endet. Die entsprechenden Auswirkungen und einige Workarounds für das Problem sind in Abschnitt 12.7, „MySQL-Volltextsuche“ beschrieben.

- Zwar wird die Verwendung mehrerer Zeichensätze innerhalb einer Tabelle unterstützt, aber alle Spalten in einem `FULLTEXT`-Index müssen denselben Zeichensatz und dieselbe Sortierung haben.

- Die `MATCH()`-Spaltenliste muss exakt mit der Spaltenliste in einer `FULLTEXT`-Indexdefinition der Tabelle übereinstimmen, sofern für `MATCH()` nicht der Modus `IN BOOLEAN MODE` aktiviert ist. Die boolesche Suche kann auch in nichtindizierten Spalten erfolgen, ist dann allerdings recht langsam.

- Das Argument `AGAINST()` muss eine String-Konstante sein.

### 12.7.5. MySQL-Volltextsuche feineinstellen

Die Volltextsuchfunktion von MySQL bietet einige wenige vom Benutzer einstellbare Parameter. Sie können mehr Kontrolle über das Verhalten der Volltextsuche erhalten, wenn Sie eine MySQL-Quelldistribution verwenden, denn einige Änderungen erfordern Anpassungen am Quellcode. Siehe auch Abschnitt 2.8, „Installation der Quelldistribution“.

Beachten Sie, dass die Volltextsuche standardmäßig bereits für maximale Effektivität optimiert ist. Eine Modifikation des Standardverhaltens kann in den meisten Fällen zu einer Verringerung der Effizienz führen. Ändern Sie den MySQL-Quellcode nur dann, wenn Sie genau wissen, was Sie tun!

Die meisten Volltextvariablen, die in diesem Abschnitt beschrieben werden, müssen beim Serverstart eingestellt werden. Um sie zu ändern, ist ein Serverneustart erforderlich – eine Modifikation bei laufendem Server ist nicht möglich.

Einige Variablenänderungen erfordern eine Neuerstellung der `FULLTEXT`-Indizes in Ihren Tabellen. Hinweise hierzu finden Sie am Ende dieses Abschnitts.

- Die minimalen und maximalen Längen von zu indizierenden Wörtern werden mit den Systemvariablen `ft_min_word_len` und `ft_max_word_len` definiert. (Siehe auch Abschnitt 5.2.2, „Server-Systemvariablen“.) Die standardmäßige Mindestlänge beträgt vier Zeichen, die vorgabeseitige Höchstlänge hängt von der Version ab. Wenn Sie einen der Werte ändern, müssen Sie ihre `FULLTEXT`-Indizes neu erstellen. Wünschen Sie beispielsweise, dass Wörter mit drei Zeichen durchsucht werden können sollen, dann können Sie die Variable `ft_min_word_len` umstellen, indem Sie die folgenden Zeilen in eine Optionsdatei schreiben:

      [mysqld]
      ft_min_word_len=3

  Danach müssen Sie den Server neu starten und die `FULLTEXT`-Indizes neu erstellen. Beachten Sie insbesondere die Anmerkungen zu myisamchk in der Anleitung, die auf diese Liste folgt.

- Um die standardmäßige Stoppwortliste außer Kraft zu setzen, müssen Sie die Systemvariable `ft_stopword_file` einstellen. (Siehe auch Abschnitt 5.2.2, „Server-Systemvariablen“.) Der Variablenwert sollte der Pfadname zu der Datei, die die Stoppwortliste enthält, oder der Leer-String sein (in diesem Fall wird die Stoppwortfilterung deaktiviert). Nachdem Sie den Wert dieser Variablen oder den Inhalt der Stoppwortdatei geändert haben, starten Sie den Server neu und erstellen Ihre `FULLTEXT`-Indizes dann neu.

  Die Stoppwortliste hat eine freie Form, d. h., Sie können beliebige nichtalphanumerische Zeichen wie den Zeilenwechsel, das Leerzeichen oder das Komma verwenden, um Stoppwörter zu trennen. Ausnahmen sind der Unterstrich (`_`) und ein einzelnes Apostroph (`'`), die als Teil eines Wortes behandelt werden. Der Zeichensatz der Stoppwortliste ist der Standardzeichensatz des Servers (siehe auch Abschnitt 10.3.1, „Serverzeichensatz und -sortierfolge“).

- Die 50-Prozent-Marke für natursprachliche Suchvorgänge wird vom jeweiligen Gewichtungsschema bestimmt. Um sie zu deaktivieren, suchen Sie in `myisam/ftdefs.h` nach der folgenden Zeile:

      #define GWS_IN_USE GWS_PROB

  Ändern Sie sie wie folgt ab:

      #define GWS_IN_USE GWS_FREQ

  Dann kompilieren Sie MySQL neu. In diesem Fall ist es nicht notwendig, die Indizes neu zu erstellen. Hinweis: Durch diese Änderung beeinträchtigen Sie die Fähigkeit von MySQL zur Bereitstellung passender Relevanzwerte für die Funktion `MATCH()` erheblich. Wenn Sie tatsächlich nach solchen gängigen Wörtern suchen müssen, sollten Sie stattdessen im Modus `IN BOOLEAN MODE` suchen, denn bei diesem wird die 50-Prozent-Marke ignoriert.

- Um die für die boolesche Volltextsuche verwendeten Operatoren zu ändern, stellen Sie die Systemvariable `ft_boolean_syntax` ein. Diese Variable kann zur Laufzeit des Servers geändert werden, allerdings benötigen Sie hierfür die Berechtigung `SUPER`. Eine Neuerstellung der Indizes ist in diesem Fall nicht notwendig. Weitere Informationen finden Sie in Abschnitt 5.2.2, „Server-Systemvariablen“, wo auch die Regeln für die Einstellung dieser Variablen beschrieben werden.

Wenn Sie Volltextvariablen ändern, die die Indizierung beeinflussen (`ft_min_word_len`, `ft_max_word_len` oder `ft_stopword_file`), oder die Stoppwortdatei selbst ändern, müssen Sie Ihre `FULLTEXT`-Indizes nach Durchführung der Änderungen und dem Neustart des Servers neu erstellen. Um die Indizes in diesem Fall neu zu erstellen, reicht es aus, eine `QUICK`-Reparaturoperation durchzuführen:

    mysql> REPAIR TABLE tbl_name QUICK;

Beachten Sie, dass, wenn Sie mit myisamchk eine Operation durchführen, die die Tabellenindizes verändert (dies können etwa Reparatur- oder Analyseoperationen sein), die `FULLTEXT`-Indizes unter Verwendung der standardmäßigen Volltextparameterwerte für die minimale und maximale Wortlänge und die Stoppwortdatei verwendet werden, sofern Sie nichts anderes angeben. Dies kann dazu führen, dass Abfragen fehlschlagen.

Das Problem tritt auf, weil diese Parameter nur dem Server bekannt sind. Sie werden nicht in den `MyISAM`-Indexdateien gespeichert. Um das Problem zu umgehen, wenn Sie die Werte für die minimale oder maximale Wortlänge oder die Stoppwortdatei am Server geändert haben, geben Sie dieselben Werte `ft_min_word_len`, `ft_max_word_len` und `ft_stopword_file` für myisamchk an, die Sie für mysqld verwendet haben. Haben Sie also beispielsweise die Mindestwortlänge auf 3 gesetzt, dann können Sie eine Tabelle mit myisamchk wie folgt reparieren:

    shell> myisamchk --recover --ft_min_word_len=3 tbl_name.MYI

Wenn Sie gewährleisten wollen, dass myisamchk und der Server dieselben Werte für Volltextparameter verwenden, können Sie sie jeweils in die Abschnitte `[mysqld]` und `[myisamchk]` einer Optionsdatei eintragen:

    [mysqld]
    ft_min_word_len=3

    [myisamchk]
    ft_min_word_len=3

Eine Alternative zur Verwendung von myisamchk besteht in der Nutzung von `REPAIR TABLE`-, `ANALYZE TABLE`-, `OPTIMIZE TABLE`- oder `ALTER TABLE`-Anweisungen. Diese Anweisungen werden vom Server ausgeführt, der die korrekten Werte der Volltextparameter kennt.

## 12.8. Cast-Funktionen und Operatoren

- `BINARY`

  Der Operator `BINARY` wandelt den ihm nachfolgenden String in einen Binär-String um. Dies ist eine einfache Möglichkeit, einen Spaltenvergleich byte- statt zeichenweise durchzuführen. Auf diese Weise unterscheidet der Vergleich die Groß-/Kleinschreibung auch dann, wenn die Spalte nicht als `BINARY` oder `BLOB` definiert ist. `BINARY` berücksichtigt auch am Ende stehende Leerzeichen.

      mysql> SELECT 'a' = 'A';
              -> 1
      mysql> SELECT BINARY 'a' = 'A';
              -> 0
      mysql> SELECT 'a' = 'a ';
              -> 1
      mysql> SELECT BINARY 'a' = 'a ';
              -> 0

  In einem Vergleich wirkt sich `BINARY` auf die gesamte Operation aus. Es kann vor einen beliebigen Operanden gesetzt werden – das Ergebnis bleibt stets das Gleiche.

  `BINARY `str`` ist eine Abkürzung für `CAST(`str` AS BINARY)`.

  Beachten Sie, dass, wenn Sie in bestimmten Kontexten eine indizierte Spalte in `BINARY` umwandeln, MySQL den Index nicht mehr effizient verwenden kann.

- `CAST(`expr` AS `type`)`, `CONVERT(`expr`,`type`)`, `CONVERT(`expr` USING `transcoding_name`)`

  Die Funktionen `CAST()` und `CONVERT()` nehmen einen Wert eines Typs entgegen und erzeugen einen Wert eines anderen Typs.

  `type` kann einen der folgenden Werte haben:

  - `BINARY[(`N`)]`

  - `CHAR[(`N`)]`

  - `DATE`

  - `DATETIME`

  - `DECIMAL`

  - `SIGNED [INTEGER]`

  - `TIME`

  - `UNSIGNED [INTEGER]`

  `BINARY` erzeugt einen String des Datentyps `BINARY`. Eine Erläuterung, wie sich dies auf Vergleiche auswirkt, finden Sie in Abschnitt 11.4.2, „Die `BINARY`- und `VARBINARY`-Typen“. Wird die optionale Länge `N` angegeben, dann verwendet `BINARY[`N`]` zur Umwandlung nicht mehr als `N` Bytes des Arguments. Werte, die kürzer als `N` Bytes sind, werden mit `0x00`-Bytes auf die Länge `N` aufgefüllt.

  Mit `CHAR[`N`]` werden bei der Umwandlung nicht mehr als `N` Zeichen des Arguments verwendet.

  `CAST()` und `CONVERT(... USING ...)` sind SQL-Standardsyntax. Die Form von `CONVERT()` ohne `USING` hingegen ist ODBC-Syntax.

  `CONVERT()` wird mit `USING` zur Konvertierung von Daten zwischen verschiedenen Zeichensätzen konvertiert. Bei MySQL sind die Transkodierungs- mit den entsprechenden Zeichensatznamen identisch. Die folgende Anweisung beispielsweise konvertiert den String `'abc'` im Standardzeichensatz in den entsprechenden String im Zeichensatz `utf8`:

      SELECT CONVERT('abc' USING utf8);

Normalerweise können Sie einen `BLOB`-Wert oder einen anderen binären Wert nur mit Unterscheidung der Groß-/Kleinschreibung vergleichen, da Binär-Strings keinen Zeichensatz (und deswegen auch keine Groß-/Kleinschreibung) haben. Um einen Vergleich ohne Unterscheidung der Groß-/Kleinschreibung durchzuführen, konvertieren Sie den Wert mit der Funktion `CONVERT()` in einen nichtbinären String. Wenn der Zeichensatz des Ergebnisses eine Sortierung mit Unterscheidung der Groß-/Kleinschreibung hat, dann unterscheidet die `LIKE`-Operation die Groß-/Kleinschreibung nicht:

    SELECT 'A' LIKE CONVERT(blob_col USING latin1) FROM tbl_name;

Um einen anderen Zeichensatz zu verwenden, ersetzen Sie `latin1` in der obigen Anweisung durch dessen Namen. Wenn Sie gewährleisten wollen, dass eine Sortierung ohne Unterscheidung der Groß-/Kleinschreibung verwendet wird, geben Sie auf den Aufruf von `CONVERT()` folgend eine `COLLATE`-Klausel an.

`CONVERT()` kann – allgemeiner gesagt – für den Vergleich von Strings verwendet werden, die in unterschiedlichen Zeichensätzen dargestellt werden.

Die Umwandlungsfunktionen sind nützlich, um eine Spalte eines bestimmten Typs in einer `CREATE ... SELECT`-Anweisung zu erstellen:

    CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE);

Die Funktionen können auch praktisch sein, um `ENUM`-Spalten in lexikaler Reihenfolge zu sortieren. Normalerweise erfolgt die Sortierung von `ENUM`-Spalten unter Verwendung der internen numerischen Werte. Die Umwandlung der Werte in `CHAR` führt zu einer lexikalen Sortierung:

    SELECT enum_col FROM tbl_name ORDER BY CAST(enum_col AS CHAR);

`CAST(`str` AS BINARY)` ist das Gleiche wie `BINARY `str``. `CAST(`expr` AS CHAR)` behandelt den Ausdruck als String mit dem Standardzeichensatz.

`CAST()` ändert das Ergebnis auch, wenn Sie es als Teil eines komplexeren Ausdrucks wie etwa `CONCAT('Date: ',CAST(NOW() AS DATE))` verwenden.

Sie sollten `CAST()` nicht zur Extraktion von Daten in verschiedenen Formaten benutzen, sondern stattdessen String-Funktionen wie `LEFT()` oder `EXTRACT()` verwenden. Siehe auch Abschnitt 12.5, „Datums- und Zeitfunktionen“.

Um einen String in einem Zahlenkontext in einen numerischen Wert umzuwandeln, müssen Sie normalerweise nichts anderes tun, als den String-Wert wie eine Zahl zu verwenden:

    mysql> SELECT 1+'1';
           -> 2

Wenn Sie eine Zahl im String-Kontext verwenden, wird die Zahl automatisch in einen `BINARY`-String konvertiert.

    mysql> SELECT CONCAT('hello you ',2);
            -> 'hello you 2'

MySQL unterstützt Berechnungen mit vorzeichenbehafteten wie auch vorzeichenlosen 64-Bit-Werten. Wenn Sie numerische Operationen (wie `+`) verwenden und einer der Operanden ein vorzeichenloser Integer ist, dann ist auch das Ergebnis vorzeichenlos. Sie können dieses Verhalten außer Kraft setzen, indem Sie die Umwandlungsoperatoren `SIGNED` und `UNSIGNED` zur Umwandlung des Operanden in einen vorzeichenbehafteten bzw. vorzeichenlosen 64-Bit-Integer benutzen.

    mysql> SELECT CAST(1-2 AS UNSIGNED)
            -> 18446744073709551615
    mysql> SELECT CAST(CAST(1-2 AS UNSIGNED) AS SIGNED);
            -> -1

Beachten Sie, dass, wenn ein Operand ein Fließkommawert ist, das Ergebnis ebenfalls ein Fließkommawert sein wird; die obige Regel findet in diesem Fall keine Anwendung. (In diesem Kontext werden `DECIMAL`-Spalten als Fließkommawerte betrachtet.)

    mysql> SELECT CAST(1 AS UNSIGNED) - 2.0;
            -> -1.0

Wenn Sie in einer Rechenoperation einen String verwenden, dann wird dieser in eine Fließkommazahl umgewandelt.

Konvertieren Sie einen „Nulldatums“-String in ein Datum, dann geben `CONVERT()` und `CAST()` `NULL` zurück und erzeugen bei aktiviertem SQL-Modus `NO_ZERO_DATE` außerdem eine Warnung.

## 12.9. XML-Funktionen

Dieser Abschnitt beschreibt XML und zugehörige Funktionalitäten in MySQL.

Beachten Sie, dass es möglich ist, in den MySQL-Clients mysql und mysqldump eine XML-formatierte Ausgabe zu erhalten, indem man sie mit der Option `--xml` aufruft. Siehe auch Abschnitt 8.5, „mysql — Das MySQL-Befehlszeilenwerkzeug mysql“, und Abschnitt 8.10, „mysqldump — Programm zur Datensicherung“.

Seit Version 5.1.5 enthält MySQL zwei Funktionen, die grundlegende XPath-Funktionalitäten (XML Path Language) bereitstellen.

Beachten Sie, dass sich diese Funktionen derzeit noch in Entwicklung befinden. Wir werden diese und andere Aspekte von XML und XPath in MySQL 5.1 und höher kontinuierlich verbessern. Sie können diese Funktionen im MySQL XML User Forum diskutieren, Fragen stellen und entsprechende Hilfe von anderen Benutzern erhalten.

- `ExtractValue(`xml_frag`, `xpath_expr`)`

  Diese Funktion nimmt zwei String-Argumente – ein XML-Fragment `xml_frag` und einen XPath-Ausdruck `xpath_expr` (auch Lokator genannt) – entgegen und gibt den `xpath_expr` entsprechenden Wert zurück. Beachten Sie, dass `ExtractValue()` nur das `CDATA` zurückgibt, das direkt im `xpath_expr` entsprechenden Tag enthalten ist, nicht jedoch Tags, die innerhalb des entsprechenden Tags enthalten sind, oder deren Inhalte (siehe auch das als `val1` im folgenden Beispiel zurückgegebene Ergebnis).

  Wird keine Übereinstimmung für `xpath_expr` gefunden, dann gibt die Funktion einen Leer-String zurück. Werden mehrere Übereinstimmungen gefunden, dann werden die Inhalte aller entsprechenden Elemente (in der Reihenfolge der Übereinstimmung) in einem leerzeichengetrennten String zurückgegeben.

      mysql> SELECT
          ->   ExtractValue('<a>ccc<b>ddd</b></a>', '/a') AS val1,
          ->   ExtractValue('<a>ccc<b>ddd</b></a>', '/a/b') AS val2,
          ->   ExtractValue('<a>ccc<b>ddd</b></a>', '//b') AS val3,
          ->   ExtractValue('<a>ccc<b>ddd</b></a>', '/b') AS val4,
          ->   ExtractValue('<a>ccc<b>ddd</b><b>eee</b></a>', '//b') AS val5;

      +------+------+------+------+---------+
      | val1 | val2 | val3 | val4 | val5    |
      +------+------+------+------+---------+
      | ccc  | ddd  | ddd  |      | ddd eee |
      +------+------+------+------+---------+

- `UpdateXML(`xml_target`, `xpath_expr`, `new_xml`)`

  Diese Funktion ersetzt einen Teil eines gegebenen XML-Fragments `xml_target` durch ein neues XML-Fragment `new_xml` und gibt das geänderte XML dann zurück. Der Teil von `xml_target`, der ersetzt wird, entspricht einem XPath-Ausdruck `xpath_expr`, der vom Benutzer übergeben wurde. Wird kein Ausdruck entdeckt, der `xpath_expr` entspricht, dann gibt die Funktion das ursprüngliche XML-Fragment `xml_target` zurück. Alle drei Argumente müssen Strings sein.

      mysql> SELECT
          ->   UpdateXML('<a><b>ccc</b><d></d></a>', '/a', '<e>fff</e>') AS val1,
          ->   UpdateXML('<a><b>ccc</b><d></d></a>', '/b', '<e>fff</e>') AS val2,
          ->   UpdateXML('<a><b>ccc</b><d></d></a>', '//b', '<e>fff</e>') AS val3,
          ->   UpdateXML('<a><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val4
          -> \G

      *************************** 1. row ***************************
      val1: <e>fff</e>
      val2: <a><b>ccc</b><d></d></a>
      val3: <a><e>fff</e><d></d></a>
      val4: <a><b>ccc</b><e>fff</e></a>

Es folgen nun Beschreibungen und Beispiele einiger einfacher XPath-Ausdrücke:

- `/`tag``

  Entspricht `<`tag`/>`, wenn (und nur wenn) `<`tag`/>` das Stammelement ist.

  Beispiel: `/a` findet eine Übereinstimmung in `<a><b/></a>`, weil es dem äußersten Tag (Stamm-Tag) entspricht. Es entspricht nicht dem inneren `a`-Element in `<b><a/></b>`, weil es in dieser Instanz ein einem anderen Element untergeordnetes Element ist.

- `/`tag1`/`tag2``

  Entspricht `<`tag2`/>`, wenn (und nur wenn) es ein untergeordnetes Element von `<`tag1`/>` und `<`tag1`/>` das Stammelement ist.

  Beispiel: `/a/b` entspricht dem Element `b` im XML-Fragment `<a><b/></a>`, weil es ein untergeordnetes Element des Stammelements `a` ist. Keine Entsprechung liegt in `<b><a/></b>` vor, weil in diesem Fall `b` das Stammelement (und damit kein einem anderen Element untergeordnetes Element) ist. Ebenso wenig hat der XPath-Ausdruck eine Übereinstimmung in `<a><c><b/></c></a>`; hier stammt `b` zwar von `a` ab, ist aber im engen Sinne kein `a` untergeordnetes Element.

  Dieses Konstrukt ist auf drei oder mehr Elemente erweiterbar. So entspricht beispielsweise der XPath-Ausdruck `/a/b/c` dem Element `c` im Fragment `<a><b><c/></b></a>`.

- `//`tag``

  Entspricht jeder Instanz von `tag`.

  Beispiel: `//a` entspricht dem Element `a` in allen folgenden Fragmenten: `<a><b><c/></b></a>`; `<c><a><b/></a></b>`; `<c><b><a/></b></c>`.

  `//` kann mit `/` kombiniert werden. Beispielsweise entspricht `//a/b` dem Element `b` in den Fragmenten `<a><b/></a>` und `<a><b><c/></b></a>`.

- Der Operator `*` agiert als Jokerzeichen, welches jedem Element entspricht. So entspricht beispielsweise der Ausdruck `/*/b` dem Element `b` in den XML-Fragmenten `<a><b/></a>` und `<c><b/></c>`. Allerdings erzeugt der Ausdruck keine Übereinstimmung im Fragment `<b><a/></b>`, weil `b` ein einem anderen Element untergeordnetes Element sein muss. Das Jokerzeichen kann an beliebiger Position verwendet werden: Der Ausdruck `/*/b/*` entspricht jedem untergeordneten Element eines Elements `b`, welches selbst nicht das Stammelement ist.

- Mehrere Lokatoren können mit dem Operator `|` (logisches `OR`) verglichen werden. So entspricht etwa der Ausdruck `//b|//c` allen `b`- und `c`-Elementen im XML-Ziel.

- Es ist auch möglich, ein Element basierend auf dem Wert eines oder mehrerer seiner Attribute zu vergleichen. Dies erfolgt mit der Syntax ``tag`[@`attribute`="`value`"]`. So entspricht beispielsweise der Ausdruck `//b[@id="idB"]` dem zweiten Element `b` im Fragment `<a><b id="idA"/><c/><b id="idB"/></a>`. Um einen Vergleich mit einem beliebigen Element mit ``attribute`="`value`"` durchzuführen, benutzen Sie den XPath-Ausdruck `//*[`attribute`="`value`"]`.

  Um mehrere Attributwerte zu filtern, benutzen Sie einfach mehrere aufeinander folgende Attributvergleichsklauseln. Der Ausdruck `//b[@c="x"][@d="y"]` beispielsweise entspricht dem Element `<b c="x" d="y"/>` an beliebiger Stelle in einem gegebenen XML-Fragment.

  Um Elemente zu finden, für die dasselbe Attribut genau einem von mehreren Werten entspricht, müssen Sie mehrere Lokatoren benutzen, die mit dem Operator `|` verknüpft werden. Um also etwa eine Übereinstimmung für alle Elemente `b` zu erzielen, deren Attribute `c` entweder den Wert 17 oder den Wert 23 haben, verwenden Sie den Ausdruck `//b[@c="23"]|b[@c="17"]`.

Eine detaillierte Beschreibung zu Syntax und Einsatz von XPath würde den Rahmen dieses Handbuchs sprengen. Umfassende Informationen erhalten Sie unter XML Path Language (XPath) 1.0 standard. Eine nützliche Ressource für Neulinge im Bereich XPath oder für solche Leser, die ihre Kenntnisse ein wenig auffrischen wollen, ist das Zvon.org XPath Tutorial, das in mehreren Sprachen verfügbar ist.

Die von diesen Funktionen unterstützte XPath-Syntax unterliegt derzeit den folgenden Beschränkungen:

- Nodeset-Nodeset-Vergleiche (wie etwa `'/a/b[@c=@d]'`) werden nicht unterstützt. Nur Vergleiche der Form `[@`attribute`="`const`"]`, wobei `const` ein konstanter Wert ist, sind zurzeit möglich. Beachten Sie, dass Gleichheit und Ungleichheit (`=` und `!=`) die einzigen unterstützten Vergleichsoperatoren sind.

- Relative Lokatorausdrücke werden nicht unterstützt. XPath-Ausdrücke müssen mit `/` oder `//` beginnen.

- Der Operator `::` wird nicht unterstützt.

- Die folgenden XPath-Funktionen werden nicht unterstützt:

  - `id()`

  - `lang()`

  - `last()`

  - `local-name()`

  - `name()`

  - `namespace-uri()`

  - `normalize-space()`

  - `starts-with()`

  - `string()`

  - `substring-after()`

  - `substring-before()`

  - `translate()`

- Die folgenden Axes werden nicht unterstützt:

  - `following-sibling`

  - `following`

  - `preceding-sibling`

  - `preceding`

## 12.10. Weitere Funktionen

### 12.10.1. Bitfunktionen

MySQL verwendet die `BIGINT`-Arithmetik (64-Bit-Arithmetik) für Bitoperationen, d. h., diese Operatoren haben einen maximalen Bereich von 64 Bits.

- `|`

  Bit-OR:

      mysql> SELECT 29 | 15;
              -> 31

  Das Ergebnis ist ein vorzeichenloser 64-Bit-Integer.

- `&`

  Bit-AND:

      mysql> SELECT 29 & 15;
              -> 13

  Das Ergebnis ist ein vorzeichenloser 64-Bit-Integer.

- `^`

  Bit-XOR:

      mysql> SELECT 1 ^ 1;
              -> 0
      mysql> SELECT 1 ^ 0;
              -> 1
      mysql> SELECT 11 ^ 3;
              -> 8

  Das Ergebnis ist ein vorzeichenloser 64-Bit-Integer.

- `<<`

  Verschiebt eine Longlong-Zahl (`BIGINT`) nach links.

      mysql> SELECT 1 << 2;
              -> 4

  Das Ergebnis ist ein vorzeichenloser 64-Bit-Integer.

- `>>`

  Verschiebt eine Longlong-Zahl (`BIGINT`) nach rechts.

      mysql> SELECT 4 >> 2;
              -> 1

  Das Ergebnis ist ein vorzeichenloser 64-Bit-Integer.

- `~`

  Invertiert alle Bits.

      mysql> SELECT 5 & ~1;
              -> 4

  Das Ergebnis ist ein vorzeichenloser 64-Bit-Integer.

- `BIT_COUNT(`N`)`

  Gibt die Anzahl der Bits zurück, die im Argument `N` gesetzt sind.

      mysql> SELECT BIT_COUNT(29), BIT_COUNT(b'101010');
              -> 4, 3

### 12.10.2. Verschlüsselungs- und Kompressionsfunktionen

Die in diesem Abschnitt beschriebenen Funktionen führen Ver- und Entschlüsselung sowie Komprimierung und Dekomprimierung durch.

Hinweis: Die Verschlüsselungs- und Komprimierungsfunktionen geben Binär-Strings zurück. Bei vielen dieser Funktionen kann das Ergebnis willkürliche Bytewerte enthalten. Wenn Sie diese Ergebnisse speichern wollen, verwenden Sie eine `BLOB`-Spalte statt einer `CHAR`- oder `VARCHAR`-Spalte, um potenzielle Probleme zu vermeiden, die aufgrund einer Datenwertänderung durch das Entfernen von Leerzeichen am Ende entstehen könnten.

Hinweis: Für die MD5- und SHA-1-Algorithmen sind Exploits bekannt. Sie sollten deswegen die Verwendung einer anderen Verschlüsselungsfunktion in Betracht ziehen, die in diesem Abschnitt beschrieben sind.

- `AES_ENCRYPT(`str`,`key_str`)`, `AES_DECRYPT(`crypt_str`,`key_str`)`

  Diese Funktionen gestatten die Ver- und Entschlüsselung von Daten mithilfe des offiziellen AES-Algorithmus (Advanced Encryption Standard; dieser war früher als „Rijndael“ bekannt). Die Verschlüsselung erfolgt mit einem 128-Bit-Schlüssel, den Sie aber durch Modifizierung des Quellcodes auf 256 Bits erweitern können. Wir haben uns für eine Schlüsselbreite von 128 Bits entschieden, da diese bei hoher Verarbeitungsgeschwindigkeit für die meisten Zwecke ausreichend sicher ist.

  `AES_ENCRYPT()` verschlüsselt einen String und gibt einen Binär-String zurück. `AES_DESCRIPT()` entschlüsselt den verschlüsselten String und gibt den Original-String zurück. Die Eingabeargumente dürfen eine beliebige Länge haben. Wenn eines der Argumente `NULL` ist, ist das Ergebnis dieser Funktion ebenfalls `NULL`.

  Da AES als Algorithmus auf Blockebene arbeitet, werden Strings unterschiedlicher Länge bei der Verschlüsselung mit Füllzeichen erweitert. Die Länge des Ergebnis-Strings lässt sich mit folgender Formel berechnen:

      16 × (trunc(string_length / 16) + 1)

  Wenn `AES_DECRYPT()` ungültige Daten oder ein inkorrektes Auffüllen erkennt, gibt es `NULL` zurück. Es ist allerdings möglich, dass `AES_DECRYPT()` einen Nicht-`NULL`-Wert zurückgibt, wenn Eingabedaten oder Schlüssel ungültig sind. (Der Rückgabewert ist dann in aller Regel unsinnig).

  Sie können die AES-Funktionen zur Speicherung von Daten in verschlüsselter Form verwenden, indem Sie Ihre Abfragen abändern:

      INSERT INTO t VALUES (1,AES_ENCRYPT('text','password'));

  `AES_ENCRYPT()` und `AES_DECRYPT()` können als die aus kryptografischer Sicht sichersten Verschlüsselungsfunktionen gelten, die derzeit in MySQL zur Verfügung stehen.

- `COMPRESS(`string_to_compress`)`

  Komprimiert einen String und gibt das Ergebnis als Binär-String zurück. Diese Funktion erfordert es, dass MySQL mit einer Komprimierungsbibliothek wie etwa `zlib` kompiliert wurde. Andernfalls ist der Rückgabewert immer `NULL`. Der komprimierte String kann mit `UNCOMPRESS()` wieder dekomprimiert werden.

      mysql> SELECT LENGTH(COMPRESS(REPEAT('a',1000)));
              -> 21
      mysql> SELECT LENGTH(COMPRESS(''));
              -> 0
      mysql> SELECT LENGTH(COMPRESS('a'));
              -> 13
      mysql> SELECT LENGTH(COMPRESS(REPEAT('a',16)));
              -> 15

  Der Inhalt des komprimierten Strings wird wie folgt gespeichert:

  - Leere Strings werden als Leer-Strings gespeichert.

  - Nichtleere Strings werden als unkomprimierte Strings mit einer Länge von 4 Byte gespeichert (wobei das niedrigste Byte zuerst kommt), gefolgt vom komprimierten String. Wenn der String mit einem Leerzeichen endet, wird ein zusätzliches Zeichen ‘`.`’ hinzugefügt, um Probleme mit dem Abschneiden von Leerzeichen am Ende für den Fall zu vermeiden, dass das Ergebnis in einer `CHAR`- oder `VARCHAR`-Spalte gespeichert wird. (Von der Verwendung von `CHAR` oder `VARCHAR` zur Speicherung komprimierter Strings wird abgeraten. Verwenden Sie stattdessen besser eine `BLOB`-Spalte.)

- `DECODE(`crypt_str`,`pass_str`)`

  Entschlüsselt den verschlüsselten String `crypt_str` mit `pass_str` als Passwort. `crypt_str` sollte ein String sein, der von `ENCODE()` zurückgegeben wurde.

- `ENCODE(`str`,`pass_str`)`

  Verschlüsselt `str` unter Verwendung von `pass_str` als Passwort. Zur Entschlüsselung des Ergebnisses verwenden Sie `DECODE()`.

  Das Ergebnis ist ein Binär-String derselben Länge wie `str`.

- `DES_DECRYPT(`crypt_str`[,`key_str`])`

  Entschlüsselt einen String, der mit `DES_ENCRYPT()` verschlüsselt wurde. Wenn ein Fehler auftritt, gibt die Funktion `NULL` zurück.

  Beachten Sie, dass diese Funktion nur funktioniert, wenn MySQL mit SSL-Unterstützung konfiguriert wurde. Siehe auch Abschnitt 5.9.7, „Verwendung sicherer Verbindungen“.

  Wird kein Argument `key_str` angegeben, dann untersucht `DES_DECRYPT()` das erste Byte des verschlüsselten Strings, um die DES-Schlüsselnummer zu ermitteln, die zur Verschlüsselung des ursprünglichen Strings verwendet wurde, und liest den Schlüssel dann aus der DES-Schlüsseldatei aus, um die Nachricht zu entschlüsseln. Damit dies klappt, benötigt der Benutzer die Berechtigung `SUPER`. Die Schlüsseldatei kann mit der Serveroption `--des-key-file` angegeben werden.

  Wenn Sie der Funktion ein Argument `key_str` übergeben, wird dieser String als Schlüssel zur Entschlüsselung der Nachricht verwendet.

  Wenn das Argument `crypt_str` kein verschlüsselter String zu sein scheint, gibt MySQL den übergebenen String `crypt_str` zurück.

- `DES_ENCRYPT(`str`[,(`key_num`|`key_str`)])`

  Verschlüsselt den String mit dem angegebenen Schlüssel unter Verwendung des Triple-DES-Algorithmus.

  Beachten Sie, dass diese Funktion nur funktioniert, wenn MySQL mit SSL-Unterstützung konfiguriert wurde. Siehe auch Abschnitt 5.9.7, „Verwendung sicherer Verbindungen“.

  Der für die Verschlüsselung zu verwendende Schlüssel wird basierend auf dem zweiten Argument zu `DES_ENCRYPT()` (sofern vorhanden) ausgewählt:

  Argument | Beschreibung
  Kein Argument | Der erste Schlüssel aus der DES-Schlüsseldatei wird verwendet.
  `key_num` | Der angegebene Schlüssel (0 bis 9) aus der DES-Schlüsseldatei wird verwendet.
  `key_str` | Der angegebene String wird zur Verschlüsselung von `str` benutzt.

  Die Schlüsseldatei kann mit der Serveroption `--des-key-file` angegeben werden.

  Der Rückgabe-String ist ein Binär-String, bei dem das erste Zeichen `CHAR(128 | key_num)` ist. Wenn ein Fehler auftritt, gibt `DES_ENCRYPT()` `NULL` zurück.

  Die 128 wird hinzugefügt, um die Erkennung eines verschlüsselten Schlüssels zu erleichtern. Wenn Sie einen String-Schlüssel verwenden, ist `key_num` 127.

  Die String-Länge des Ergebnisses wird mit dieser Formel angegeben:

      new_len = orig_len + (8 - (orig_len % 8)) + 1

  Jede Zeile in der DES-Schlüsseldatei hat das folgende Format:

      key_num des_key_str

  Jeder `key_num`-Wert muss eine Zahl zwischen `0` und `9` sein. Die Zeilen können in der Datei beliebig sortiert sein. `des_key_str` ist der String, der zur Verschlüsselung der Nachricht verwendet wird. Es sollte mindestens ein Leerzeichen zwischen der Zahl und dem Schlüssel stehen. Der erste Schlüssel ist der Standardschlüssel: Er wird benutzt, wenn kein Schlüsselargument für `DES_ENCRYPT()` angegeben wurde.

  Sie können MySQL mit der Anweisung `FLUSH DES_KEY_FILE` anweisen, neue Schlüsselwerte aus der Schlüsseldatei einzulesen. Dies erfordert die Berechtigung `RELOAD`.

  Ein Vorteil der Verwendung eines Satzes mit Standardschlüsseln besteht darin, dass dies Anwendungen eine Möglichkeit bietet, auf das Vorhandensein verschlüsselter Spaltenwerte zu prüfen, ohne dem Endbenutzer das Recht zur Verschlüsselung dieser Werte zu geben.

      mysql> SELECT customer_address FROM customer_table
           > WHERE crypted_credit_card = DES_ENCRYPT('credit_card_number');

- `ENCRYPT(`str`[,`salt`])`

  Verschlüsselt `str` unter Verwendung des Unix-Systemaufrufs `crypt()` und gibt einen Binär-String zurück. Das Argument `salt` sollte ein String mit mindestens zwei Zeichen sein. Wird kein `salt`-Argument angegeben, dann wird ein zufälliger Wert verwendet.

      mysql> SELECT ENCRYPT('hello');
              -> 'VxuFAJXVARROc'

  `ENCRYPT()` ignoriert zumindest auf einigen Systemen alle bis auf die ersten acht Zeichen von `str`. Dieses Verhalten wird von der Implementierung des zugrunde liegenden `crypt()`-Systemaufrufs bestimmt.

  Wenn `crypt()` nicht auf Ihrem System verfügbar ist (wie es bei Windows der Fall ist), gibt `ENCRYPT()` immer `NULL` zurück.

- `MD5(`str`)`

  Berechnet eine MD5-Prüfsumme mit 128 Bits für den String. Der Wert wird als 32 Hexadezimalstellen umfassender Binär-String zurückgegeben. Ist das Argument `NULL`, so wird auch `NULL` zurückgegeben. Der Rückgabewert kann z. B. als Hash-Schlüssel verwendet werden.

      mysql> SELECT MD5('testing');
              -> 'ae2b1fca515949e5d54fb22b8ed95575'

  Dies ist der „MD5-Message-Digest-Algorithmus“ von RSA Data Security, Inc.

  Wenn Sie den Wert in Großbuchstaben konvertieren wollen, lesen Sie die Beschreibung zur Konvertierung von Binär-Strings im Abschnitt zum Operator `BINARY` (Abschnitt 12.8, „Cast-Funktionen und Operatoren“).

  Beachten Sie auch die Anmerkung zum MD5-Algorithmus am Anfang dieses Abschnitts.

- `OLD_PASSWORD(`str`)`

  `OLD_PASSWORD()` wurde zu MySQL hinzugefügt, als die Implementierung von `PASSWORD()` geändert wurde, um die Sicherheit zu verbessern. `OLD_PASSWORD()` gibt den Wert der alten (d. h. vor Version 4.1 verwendeten) Implementierung von `PASSWORD()` als Binär-String zurück und soll Ihnen das Zurücksetzen von Passwörtern auf Clients vor Version 4.1 gestatten, die mit Ihrem MySQL Server unter Version 5.1 eine Verbindung herstellen können sollen, ohne ausgesperrt zu werden. Siehe auch Abschnitt 5.8.9, „Kennwort-Hashing ab MySQL 4.1“.

- `PASSWORD(`str`)`

  Berechnet einen Passwort-String aus dem Klartextpasswort `str` und gibt diesen zurück. Der Rückgabewert ist ein Binär-String oder aber `NULL`, sofern das Argument `NULL` war. Diese Funktion wird zur Verschlüsselung von MySQL-Passwörtern zur Speicherung in der Spalte `Password` der Grant-Tabelle `user` benutzt.

      mysql> SELECT PASSWORD('badpwd');
              -> '*AAB3E285149C0135D51A520E1940DD3263DC008C'

  Die `PASSWORD()`-Verschlüsselung ist unidirektional (d. h. unumkehrbar).

  `PASSWORD()` führt keine Passwortverschlüsselung in der Art der Verschlüsselung von Unix-Passwörtern durch. Siehe auch `ENCRYPT()`.

  Hinweis: Die Funktion `PASSWORD()` wird in MySQL Server vom Authentifizierungssystem verwendet. Sie sollten Sie nicht in Ihren eigenen Anwendungen einsetzen. Ziehen Sie zu diesem Zweck eher `MD5()` oder `SHA1()` in Betracht. Ferner können Sie RFC 2195 weitere Informationen zum sicheren Umgang mit Passwörtern und Authentifizierung in Ihren Anwendungen entnehmen.

- `SHA1(`str`)`, `SHA(`str`)`

  Berechnet eine 160 Bits umfassende SHA-1-Prüfsumme für den String. (Siehe auch RFC 3174 mit dem Titel „Secure Hash Algorithm“). Der Wert wird als 40 Hexadezimalstellen umfassender Binär-String zurückgegeben. Ist das Argument `NULL`, so wird auch `NULL` zurückgegeben. Diese Funktion lässt sich etwa für die Erstellung eines Hash-Schlüssels verwenden. Sie können sie auch als Kryptografiefunktion zur Speicherung von Passwörtern verwenden. `SHA()` ist synonym zu `SHA1()`.

      mysql> SELECT SHA1('abc');
              -> 'a9993e364706816aba3e25717850c26c9cd0d89d'

  `SHA1()` kann als aus kryptografischer Sicht sichereres Äquivalent zu `MD5()` betrachtet werden. Allerdings sollten Sie auch die Anmerkung zu den MD5- und SHA-1-Algorithmen am Anfang dieses Abschnitts beachten.

- `UNCOMPRESS(`string_to_uncompress`)`

  Entkomprimiert einen String, der mit der Funktion `COMPRESS()` komprimiert wurde. Wenn dieses Argument kein komprimierter Wert ist, ist das Ergebnis `NULL`. Diese Funktion erfordert es, dass MySQL mit einer Komprimierungsbibliothek wie etwa `zlib` kompiliert wurde. Andernfalls ist der Rückgabewert immer `NULL`.

      mysql> SELECT UNCOMPRESS(COMPRESS('any string'));
              -> 'any string'
      mysql> SELECT UNCOMPRESS('any string');
              -> NULL

- `UNCOMPRESSED_LENGTH(`compressed_string`)`

  Gibt die Länge zurück, die der komprimierte String vor der Länge hatte.

      mysql> SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
              -> 30

### 12.10.3. Informationsfunktionen

- `BENCHMARK(`count`,`expr`)`

  Die Funktion `BENCHMARK()` wiederholt die Ausführung des Ausdrucks `expr` mit der mit `count` angegebenen Häufigkeit. Sie kann verwendet werden, um zu ermitteln, wie schnell MySQL den Ausdruck verarbeitet. Der Ergebniswert ist immer `0`. Vorgesehen ist die Verwendung dieser Funktion aus dem Client mysql heraus. Dieser gibt dann die Ausführungszeiten der Abfrage an:

      mysql> SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
      +----------------------------------------------+
      | BENCHMARK(1000000,ENCODE('hello','goodbye')) |
      +----------------------------------------------+
      |                                            0 |
      +----------------------------------------------+
      1 row in set (4.74 sec)

  Die gemeldete Zeit ist die auf der Clientseite verstrichene Zeit und nicht die Prozessorzeit auf der Serverseite. Wir empfehlen die mehrfache Ausführung von `BENCHMARK()` und die Interpretation des Ergebnisses im Hinblick darauf, wie hoch die Belastung des Servercomputers ist.

- `CHARSET(`str`)`

  Gibt den Zeichensatz des String-Arguments zurück.

      mysql> SELECT CHARSET('abc');
              -> 'latin1'
      mysql> SELECT CHARSET(CONVERT('abc' USING utf8));
              -> 'utf8'
      mysql> SELECT CHARSET(USER());
              -> 'utf8'

- `COERCIBILITY(`str`)`

  Gibt den Sortierfolgenvorrangswert des String-Arguments zurück.

      mysql> SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
              -> 0
      mysql> SELECT COERCIBILITY(USER());
              -> 3
      mysql> SELECT COERCIBILITY('abc');
              -> 4

  Die Rückgabewerte haben die in der folgenden Tabelle aufgeführten Bedeutungen. Niedrigere Werte haben dabei eine höhere Rangstufe.

  Sortierfolgenvorrang | Bedeutung | Beispiel
  `0` | Explizite Sortierung | Wert mit `COLLATE`-Klausel
  `1` | Keine Sortierung | Verkettung von Strings mit unterschiedlichen Sortierungen
  `2` | Implizite Sortierung | Spaltenwert, Parameter einer gespeicherten Routine oder lokale Variable
  `3` | Systemkonstante | `USER()`-Rückgabewert
  `4` | Sortierfolgenvorrang einstellbar | Literaler String
  `5` | Ignorierbar | `NULL` oder ein Ausdruck, der von `NULL` abgeleitet wurde

- `COLLATION(`str`)`

  Gibt die Sortierung des String-Arguments zurück.

      mysql> SELECT COLLATION('abc');
              -> 'latin1_swedish_ci'
      mysql> SELECT COLLATION(_utf8'abc');
              -> 'utf8_general_ci'

- `CONNECTION_ID()`

  Gibt die Verbindungskennung (Thread-ID) der Verbindung zurück. Jede Verbindung hat eine Kennung, die in der Gesamtzahl der aktuell verbundenen Clients eindeutig ist.

      mysql> SELECT CONNECTION_ID();
              -> 23786

- `CURRENT_USER`, `CURRENT_USER()`

  Gibt die Kombination aus Benutzer- und Hostnamen für das MySQL-Konto zurück, das der Server zur Authentifizierung des aktuellen Clients verwendet hat. Dieses Konto bestimmt Ihre Zugriffsberechtigungen. Innerhalb einer gespeicherten Routine, die mit dem Merkmal `SQL SECURITY DEFINER` definiert wurde, gibt `CURRENT_USER()` den Ersteller der Routine zurück. Der Rückgabewert ist ein String im Zeichensatz `utf8`.

  Der Wert von `CURRENT_USER()` kann sich vom Wert von `USER()` unterscheiden.

      mysql> SELECT USER();
              -> 'davida@localhost'
      mysql> SELECT * FROM mysql.user;
      ERROR 1044: Access denied for user ''@'localhost' to
      database 'mysql'
      mysql> SELECT CURRENT_USER();
              -> '@localhost'

  Das Beispiel veranschaulicht, dass, obwohl der Client den Benutzernamen `davida` (gemäß dem Wert der Funktion `USER()`) angegeben hat, der Server den Client unter Verwendung eines anonymen Benutzerkontos authentifiziert hat. Dies geht aus dem leeren Benutzernamensteil des `CURRENT_USER()`-Werts hervor. Eine mögliche Ursache hierfür besteht darin, dass in den Grant-Tabellen kein Konto `davida` aufgeführt ist.

- `DATABASE()`

  Gibt den Namen der Standarddatenbank (d. h. der aktuellen Datenbank) als String im Zeichensatz `utf8` zurück. Ist keine Standarddatenbank vorhanden, dann gibt `DATABASE()` `NULL` zurück. Innerhalb einer gespeicherten Routine ist die Standarddatenbank diejenige, mit der die Routine assoziiert ist. Dies muss nicht unbedingt die gleiche Datenbank sein, die als Standarddatenbank im aufrufenden Kontext verwendet wird.

      mysql> SELECT DATABASE();
              -> 'test'

  Ist keine Standarddatenbank vorhanden, dann gibt `DATABASE()` `NULL` zurück.

- `FOUND_ROWS()`

  Eine `SELECT`-Anweisung kann eine `LIMIT`-Klausel enthalten, die die Anzahl der Datensätze beschränkt, die der Server an den Client zurückgibt. In manchen Fällen kann es wünschenswert sein, zu wissen, wie viele Datensätze die Anweisung ohne `LIMIT`-Klausel zurückgegeben hätte, ohne dass man die Anweisung hierzu erneut ausführen müsste. Um diese Anzahl zu ermitteln, fügen Sie die Option `SQL_CALC_FOUND_ROWS` in die `SELECT`-Anweisung ein und rufen danach `FOUND_ROWS()` auf:

      mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
          -> WHERE id > 100 LIMIT 10;
      mysql> SELECT FOUND_ROWS();

  Die zweite `SELECT`-Anweisung gibt eine Zahl zurück, die angibt, wie viele Datensätze die erste `SELECT`-Anweisung zurückgegeben hätte, wenn die `LIMIT`-Klausel nicht enthalten gewesen wäre. (Wenn die vorangegangene `SELECT`-Anweisung die Option `SQL_CALC_FOUND_ROWS` nicht enthält, dann gibt `FOUND_ROWS()` mit `LIMIT` unter Umständen ein anderes Ergebnis als ohne.)

  Die mit `FOUND_ROWS()` ermittelte Anzahl der Datensätze ist flüchtig und sollte nicht über die der `SELECT SQL_CALC_FOUND_ROWS`-Anweisung nachfolgende Anweisung hinaus verfügbar bleiben. Wenn Sie den Wert später noch einmal benötigen sollten, dann sollten Sie ihn speichern:

      mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
      mysql> SET @rows = FOUND_ROWS();

  Wenn Sie `SELECT SQL_CALC_FOUND_ROWS` verwenden, muss MySQL berechnen, wie viele Datensätze in der vollständigen Ergebnismenge enthalten sind. Allerdings ist dies schneller, als die Abfrage ohne `LIMIT` erneut auszuführen, weil die Ergebnismenge nicht an den Client gesendet werden muss.

  `SQL_CALC_FOUND_ROWS` und `FOUND_ROWS()` können in Situationen nützlich sein, in denen Sie die Anzahl der von einer Abfrage zurückgegebenen Datensätze beschränken, aber auch die Anzahl der Datensätze im vollständigen Ergebnis ermitteln wollen, ohne die Abfrage erneut auszuführen. Ein Beispiel hierfür wäre ein Webskript, das seitenweise eine Darstellung mit Links auf Seiten anzeigt, die auf andere Bereiche eines Suchergebnisses verweisen. Mithilfe von `FOUND_ROWS()` können Sie bestimmen, wie viele andere Seiten für den Rest des Ergebnisses benötigt werden.

  Die Verwendung von `SQL_CALC_FOUND_ROWS` und `FOUND_ROWS()` ist bei `UNION`-Anweisungen komplexer als bei einfachen `SELECT`-Anweisungen, weil `LIMIT` an mehreren Stellen in einer `UNION` auftreten kann. Es kann auf einzelne `SELECT`-Anweisungen in der `UNION` oder aber global auf das Ergebnis der `UNION` als Ganzes angewendet werden.

  Der Zweck von `SQL_CALC_FOUND_ROWS` bei `UNION` besteht in der Rückgabe der Anzahl von Datensätzen, die ohne globale `LIMIT`-Klausel zurückgegeben worden wäre. Die Benutzung von `SQL_CALC_FOUND_ROWS` mit `UNION` ist folgenden Bedingungen unterworfen:

  - Das Schlüsselwort `SQL_CALC_FOUND_ROWS` muss in der ersten `SELECT`-Anweisung der `UNION` auftreten.

  - Der Wert von `FOUND_ROWS()` ist nur exakt, wenn `UNION ALL` verwendet wird. Wenn `UNION` ohne `ALL` verwendet wird, findet eine Entfernung von Dubletten statt, weswegen der Wert von `FOUND_ROWS()` nur näherungsweise ist.

  - Wenn `LIMIT` nicht in der `UNION` vorhanden ist, wird `SQL_CALC_FOUND_ROWS` ignoriert und gibt die Anzahl der Reihen in der Temporärtabelle zurück, die zur Verarbeitung der `UNION` verwendet wird.

- `LAST_INSERT_ID()`, `LAST_INSERT_ID(`expr`)`

  Gibt den ersten automatisch erzeugten Wert zurück, der für eine `AUTO_INCREMENT`-Spalte durch die aktuelle `INSERT`- oder `UPDATE`-Anweisung eingestellt wurde, die eine solche Spalte modifiziert hat.

      mysql> SELECT LAST_INSERT_ID();
              -> 195

  Die erzeugte Kennung wird auf dem Server verbindungsspezifisch gehandhabt: Der von der Funktion an einen bestimmten Client zurückgegebene Wert ist der erste `AUTO_INCREMENT`-Wert, der für die zuletzt abgesetzte Anweisung, die eine `AUTO_INCREMENT`-Spalte betraf, von diesem Client erzeugt wurde. Dieser Wert darf nicht von anderen Clients bearbeitet werden, auch wenn diese selbst `AUTO_INCREMENT`-Werte erzeugen. Dieses Verhalten gewährleistet, dass jeder Client seine eigene Kennung abrufen kann, ohne die Aktivitäten anderer Clients berücksichtigen oder Sperren setzen bzw. Transaktionen verwenden zu müssen.

  Der Wert von `LAST_INSERT_ID()` wird nicht geändert, wenn Sie die `AUTO_INCREMENT`-Spalte eines Datensatzes auf einen „nichtmagischen“ Wert (d. h. einen Wert, der nicht `NULL` und nicht `0` ist) setzen.

  Wichtig: Wenn Sie mehrere Datensätze mithilfe einer einzelnen `INSERT`-Anweisung einfügen, gibt `LAST_INSERT_ID()` nur denjenigen Wert zurück, der für den ersten eingefügten Datensatz erzeugt wurde. Grund hierfür ist, dass es möglich sein soll, dieselbe `INSERT`-Anweisung problemlos auf einem anderen Server zu reproduzieren.

  Zum Beispiel:

      mysql> USE test;
      Database changed
      mysql> CREATE TABLE t (
          ->   id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
          ->   name VARCHAR(10) NOT NULL
          -> );
      Query OK, 0 rows affected (0.09 sec)

      mysql> INSERT INTO t VALUES (NULL, 'Bob');
      Query OK, 1 row affected (0.01 sec)

      mysql> SELECT * FROM t;
      +----+------+
      | id | name |
      +----+------+
      |  1 | Bob  |
      +----+------+
      1 row in set (0.01 sec)

      mysql> SELECT LAST_INSERT_ID();
      +------------------+
      | LAST_INSERT_ID() |
      +------------------+
      |                1 |
      +------------------+
      1 row in set (0.00 sec)

      mysql> INSERT INTO t VALUES
          -> (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
      Query OK, 3 rows affected (0.00 sec)
      Records: 3  Duplicates: 0  Warnings: 0

      mysql> SELECT * FROM t;
      +----+------+
      | id | name |
      +----+------+
      |  1 | Bob  |
      |  2 | Mary |
      |  3 | Jane |
      |  4 | Lisa |
      +----+------+
      4 rows in set (0.01 sec)

      mysql> SELECT LAST_INSERT_ID();
      +------------------+
      | LAST_INSERT_ID() |
      +------------------+
      |                2 |
      +------------------+
      1 row in set (0.00 sec)

  Obwohl die zweite `INSERT`-Anweisung drei neue Datensätze in `t` eingefügt hat, war die für den ersten dieser Datensätze erzeugte Kennung `2`, und diesen Wert hat `LAST_INSERT_ID()` auch für die folgende `SELECT`-Anweisung zurückgegeben.

  Wenn Sie `INSERT IGNORE` verwenden und der Datensatz ignoriert wird, wird der `AUTO_INCREMENT`-Zähler nicht erhöht, und `LAST_INSERT_ID()` gibt `0` zurück, um anzuzeigen, dass kein Datensatz eingefügt wurde.

  Wenn `expr` als Argument für `LAST_INSERT_ID()` angegeben wird, wird der Wert des Arguments von der Funktion zurückgegeben und als nächster Wert von `LAST_INSERT_ID()` zurückzugebender Wert vermerkt. Dies kann zur Simulierung von Sequenzen verwendet werden:

  1. Erstellen Sie eine Tabelle zur Aufnahme des Sequenzzählers und initialisieren Sie sie:

         mysql> CREATE TABLE sequence (id INT NOT NULL);
         mysql> INSERT INTO sequence VALUES (0);

  2. Erstellen Sie mit dieser Tabelle wie folgt Sequenznummern:

         mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
         mysql> SELECT LAST_INSERT_ID();

     Die `UPDATE`-Anweisung erhöht den Sequenzzähler und sorgt dafür, dass der nächste Aufruf von `LAST_INSERT_ID()` den aktualisierten Wert zurückgibt. Die `SELECT`-Anweisung ruft diesen Wert ab. Die C-API-Funktion `mysql_insert_id()` kann ebenfalls zum Abrufen des Werts verwendet werden. Siehe auch Abschnitt 24.2.3.36, „`mysql_insert_id()`“.

  Sie können Sequenzen zwar auch ohne Aufruf von `LAST_INSERT_ID()` erzeugen, aber die Funktion auf diese Weise zu verwenden hat den Vorteil, dass der Kennungswert am Server als letzter automatisch erzeugter Wert vermerkt wird. Dies ist im Multiuser-Betrieb sicher, weil mehrere Clients die Anweisung `UPDATE` absetzen und jeweils einen eigenen Sequenzwert mit der `SELECT`-Anweisung (oder `mysql_insert_id()`) erhalten, ohne andere Clients, die eigene Sequenzwerte erstellen, zu beeinträchtigen bzw. von ihnen beeinträchtigt zu werden.

  Beachten Sie, dass `mysql_insert_id()` erst nach den `INSERT`- und `UPDATE`-Anweisungen aktualisiert wird, d. h., Sie können die C-API-Funktion nicht zum Abrufen des Werts von `LAST_INSERT_ID(`expr`)` verwenden, nachdem andere SQL-Anweisungen wie `SELECT` oder `SET` ausgeführt wurden.

- `ROW_COUNT()`

  `ROW_COUNT()` gibt die Anzahl der von der vorherigen Anweisung aktualisierten, eingefügten oder gelöschten Datensätze zurück. Dies entspricht der Datensatzanzahl, die vom Client mysql angezeigt wird, und dem Wert der C-API-Funktion `mysql_affected_rows()`.

      mysql> INSERT INTO t VALUES(1),(2),(3);
      Query OK, 3 rows affected (0.00 sec)
      Records: 3  Duplicates: 0  Warnings: 0

      mysql> SELECT ROW_COUNT();
      +-------------+
      | ROW_COUNT() |
      +-------------+
      |           3 |
      +-------------+
      1 row in set (0.00 sec)

      mysql> DELETE FROM t WHERE i IN(1,2);
      Query OK, 2 rows affected (0.00 sec)

      mysql> SELECT ROW_COUNT();
      +-------------+
      | ROW_COUNT() |
      +-------------+
      |           2 |
      +-------------+
      1 row in set (0.00 sec)

- `SCHEMA()`

  Diese Funktion ist synonym zu `DATABASE()`.

- `SESSION_USER()`

  `SESSION_USER()` ist ein Synonym für `USER()`.

- `SYSTEM_USER()`

  `SYSTEM_USER()` ist ein Synonym für `USER()`.

- `USER()`

  Gibt den aktuellen MySQL-Benutzer- und Hostnamen als String im Zeichensatz `utf8` zurück.

      mysql> SELECT USER();
              -> 'davida@localhost'

  Der Wert gibt den Benutzernamen, den Sie beim Herstellen der Verbindung zum Server eingegeben haben, und den Clienthost an, über den die Verbindung hergestellt wurde. Der Wert kann sich von dem von `CURRENT_USER()` unterscheiden.

  Sie können den Benutzernamensanteil wie folgt extrahieren:

      mysql> SELECT SUBSTRING_INDEX(USER(),'@',1);
              -> 'davida'

- `VERSION()`

  Gibt einen String zurück, der die MySQL Server-Version angibt. Der String verwendet den Zeichensatz `utf8`.

      mysql> SELECT VERSION();
              -> '5.1.5-alpha-standard'

  Beachten Sie, dass, wenn Ihr Versions-String mit `-log` endet, dies bedeutet, dass das Loggen aktiviert ist.

### 12.10.4. Verschiedene Funktionen

- `DEFAULT(`col_name`)`

  Gibt den Standardwert einer Tabellenspalte zurück. Wenn die Spalte keinen Standardwert hat, wird ein Fehler erzeugt.

      mysql> UPDATE t SET i = DEFAULT(i)+1 WHERE id < 100;

- `FORMAT(`X`,`D`)`

  Formatiert die Zahl `X` in ein Format wie `'#,###,###.##'`, gerundet auf `D` Dezimalstellen, und gibt das Ergebnis als String zurück. Detaillierte Informationen finden Sie in Abschnitt 12.3, „String-Funktionen“.

- `GET_LOCK(`str`,`timeout`)`

  Versucht eine Sperre mit dem String `str` als Namen zu erwirken. Hierbei wird ein Zeitüberschreitungswert von `timeout` Sekunden angewendet. Gibt `1` zurück, wenn die Sperrung erfolgreich war, `0`, wenn es zu einer Zeitüberschreitung kam (etwa weil zuvor ein anderer Client den Namen gesperrt hatte), oder `NULL`, wenn ein Fehler aufgetreten ist (z. B. aufgrund von Speichermangel oder einer Terminierung des Threads mit mysqladmin kill). Wurde eine Sperre mit `GET_LOCK()` erwirkt, so wird diese wieder aufgehoben, wenn Sie `RELEASE_LOCK()` oder noch einmal `GET_LOCK()` ausführen oder Ihre Verbindung – gewünscht oder unvorhergesehen – endet.

  Diese Funktion kann zur Implementierung von Anwendungssperren oder zur Simulation von Datensatzsperren verwendet werden. Die Namen werden serverweit gesperrt. Wenn ein Name von einem Client gesperrt wird, blockiert `GET_LOCK()` alle weiteren Anforderungen von gleichnamigen Sperren durch andere Clients. So wiederum können Clients, die einem gegebenen Sperrennamen zustimmen, diesen Namen zur Durchführung kooperativer beratender Sperrungen verwenden. Sie müssen allerdings beachten, dass auf diese Weise auch Clients, die nicht zu den kooperierenden Clients gehören, unbeabsichtigt oder gezielt einen Namen sperren und so verhindern können, dass ein kooperierender Client den Namen sperren kann. Sie können die Wahrscheinlichkeit hierfür verringern, indem Sie Sperrnamen verwenden, die datenbank- oder anwendungsspezifisch sind. Verwenden Sie beispielsweise Sperrnamen der Form `db_name.str` oder `app_name.str`.

      mysql> SELECT GET_LOCK('lock1',10);
              -> 1
      mysql> SELECT IS_FREE_LOCK('lock2');
              -> 1
      mysql> SELECT GET_LOCK('lock2',10);
              -> 1
      mysql> SELECT RELEASE_LOCK('lock2');
              -> 1
      mysql> SELECT RELEASE_LOCK('lock1');
              -> NULL

  Der zweite `RELEASE_LOCK()`-Aufruf gibt `NULL` zurück, weil die Sperre `'lock1'` automatisch durch den zweiten `GET_LOCK()`-Aufruf aufgehoben wurde.

  Hinweis: Wenn ein Client versucht, eine Sperre zu erwirken, die bereits von einem anderen Client gehalten wird, dann erfolgt die Sperrung gemäß dem Argument `timeout`. Wird der blockierte Client beendet, dann wird der Thread erst terminiert, wenn eine Zeitüberschreitung der Sperranforderung erfolgt. Dieser Bug ist bekannt.

- `INET_ATON(`expr`)`

  Wird eine Netzwerkadresse als String in der üblichen Schreibweise (vier punktgetrennte Oktette) übergeben, dann gibt die Funktion einen Integer zurück, der den numerischen Wert der Adresse angibt. Adressen können 4 oder 8 Byte umfassen.

      mysql> SELECT INET_ATON('209.207.224.40');
              -> 3520061480

  Die Zahl wird immer in der Reihenfolge der Netzwerkbytes erzeugt. Beim obigen Beispiel wird sie als 209×2563 + 207×2562 + 224×256 + 40 berechnet.

  `INET_ATON()` versteht auch IP-Adressen in der Kurzform:

      mysql> SELECT INET_ATON('127.0.0.1'), INET_ATON('127.1');
              -> 2130706433, 2130706433

  Hinweis: Wenn Sie Werte speichern, die von `INET_ATON()` erzeugt wurden, empfehlen wir die Verwendung einer `INT UNSIGNED`-Spalte. Wenn Sie eine (vorzeichenbehaftete) `INT`-Spalte verwenden, können Werte, die IP-Adressen entsprechen, deren erstes Oktett größer als 127 ist, nicht korrekt gespeichert werden. Siehe auch Abschnitt 11.2, „Numerische Datentypen“.

- `INET_NTOA(`expr`)`

  Wenn eine numerische Netzwerkadresse mit einer Länge von 4 oder 8 Byte übergeben wird, gibt die Funktion die punktgetrennte Darstellung der Adresse als String zurück.

      mysql> SELECT INET_NTOA(3520061480);
              -> '209.207.224.40'

- `IS_FREE_LOCK(`str`)`

  Überprüft, ob die Sperre mit dem Namen `str` frei (d. h. nicht gesperrt) ist und verwendet werden kann. Gibt `1` zurück, wenn die Sperre verfügbar ist (also von niemandem benutzt wird), `0`, wenn die Sperre aktiv ist, und `NULL`, wenn ein Fehler aufgetreten ist (z. B. bei einem falschen Argument).

- `IS_USED_LOCK(`str`)`

  Überprüft, ob die Sperre mit dem Namen `str` verwendet wird (d. h. nicht gesperrt ist). Ist dies der Fall, dann wird die Verbindungskennung des Clients zurückgegeben, der die Sperre hält. Andernfalls wird `NULL` zurückgegeben.

- `MASTER_POS_WAIT(`log_name`,`log_pos`[,`timeout`])`

  Diese Funktion ist praktisch zur Steuerung der Master/Slave-Synchronisation. Sie blockiert, bis der Slave alle Änderungen bis zur im Master-Log angegebenen Position gelesen und übernommen hat. Der Rückgabewert ist die Anzahl der Logereignisse, auf die der Slave warten musste, um bis zur angegebenen Position fortschreiten zu können. Die Funktion gibt `NULL` zurück, wenn der SQL-Slave-Thread nicht gestartet wurde, die Master-Daten des Slaves nicht initialisiert wurden, die Argumente inkorrekt sind oder ein Fehler auftritt. `-1` wird bei einer Zeitüberschreitung zurückgegeben. Wenn der SQL-Slave-Thread endet, während `MASTER_POS_WAIT()` wartet, gibt die Funktion `NULL` zurück. Befindet sich der Slave bereits jenseits der angegebenen Position, dann erfolgt die Rückgabe durch die Funktion unmittelbar.

  Wenn ein `timeout`-Wert angegeben wird, beendet `MASTER_POS_WAIT()` den Wartevorgang, sobald `timeout` Sekunden verstrichen sind. `timeout` muss größer als 0 sein; ein Nullwert oder ein negativer `timeout`-Wert haben die Bedeutung „kein `timeout`-Wert“.

- `NAME_CONST(`name`,`value`)`

  Gibt den angegebenen Wert zurück. Wenn `NAME_CONST()` zur Erzeugung einer Ergebnismengenspalte verwendet wird, erhält die Spalte den angegebenen Namen.

      mysql> SELECT NAME_CONST('myname', 14);
      +--------+
      | myname |
      +--------+
      |     14 |
      +--------+

  Die Funktion wurde in MySQL 5.0.12 hinzugefügt und ist nur zur internen Verwendung vorgesehen. Der Server verwendet sie, wenn er Anweisungen aus gespeicherten Routinen schreibt, die Referenzen auf lokale Routinenvariablen haben (siehe Beschreibung in Abschnitt 19.4, „Binärloggen gespeicherter Routinen und Trigger“). Sie sehen die Funktion unter Umständen in der Ausgabe von mysqlbinlog.

- `RELEASE_LOCK(`str`)`

  Hebt die Sperre namens `str` auf, die mit `GET_LOCK()` erwirkt wurde. Gibt `1` zurück, wenn die Sperre aufgehoben wurde, `0`, wenn die Sperre nicht durch diesen Thread erwirkt worden war (wobei die Sperre auch nicht aufgehoben wird), und `NULL`, wenn der Name nicht existiert. Die Sperre existiert nicht, wenn sie niemals von einem `GET_LOCK()`-Aufruf erwirkt worden war oder zuvor bereits aufgehoben wurde.

  Die `DO`-Anweisung ist in Kombination mit `RELEASE_LOCK()` sehr praktisch. Siehe auch Abschnitt 13.2.2, „`DO`“.

- `SLEEP(`duration`)`

  Setzt eine Unterbrechung mit einer Länge von der durch `duration` angegebenen Anzahl von Sekunden und gibt dann 0 zurück. Wenn `SLEEP()` unterbrochen wird, wird 1 zurückgegeben. Die Dauer kann einen in Mikrosekunden angegebenen Bruchteil enthalten.

- `UUID()`

  Gibt eine UUID (Universal Unique Identifier) gemäß „DCE 1.1: Remote Procedure Call“ (Anhang A) der CAE-Spezifikation (Common Applications Environment Specifications), veröffentlicht von The Open Group im Oktober 1997 (Dokument Nr. C706, http://www.opengroup.org/public/pubs/catalog/c706.htm), zurück.

  Eine UUID ist eine Zahl, die in Raum und Zeit eindeutig ist. Bei zwei Aufrufen von `UUID()` wird die Erzeugung zweier vollkommen unterschiedlicher Werte erwartet – und zwar auch dann, wenn diese beiden Aufrufe auf zwei separaten Computern erfolgen, die nicht miteinander verbunden sind.

  Die UUID ist eine 128-Bit-Zahl, die durch einen String aus fünf Hexadezimalzahlen im Format `aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee` dargestellt wird:

  - Die ersten drei Zahlen werden aus einem Zeitstempel erzeugt.

  - Die vierte Zahl bewahrt die zeitbezogene Eindeutigkeit für den Fall, dass der Zeitstempel seine Monotonie verliert (z. B. aufgrund der Sommerzeit).

  - Die fünfte Zahl schließlich ist eine IEEE 802-Knotennummer, die die räumliche Eindeutigkeit gewährleistet. Ersatzweise wird eine Zufallszahl eingesetzt, wenn die Knotennummer nicht vorhanden ist (weil der Computer beispielsweise keine Ethernetkarte hat oder wir nicht wissen, wie man die Hardwareadresse einer Schnittstelle unter Ihrem Betriebssystem ermitteln kann). In diesem Fall ist die räumliche Eindeutigkeit nicht garantiert. Nichtsdestoweniger ist eine Kollision sehr unwahrscheinlich.

    Derzeit wird die MAC-Adresse einer Schnittstelle nur unter FreeBSD und Linux berücksichtigt. Unter anderen Betriebssystemen verwendet MySQL eine zufällig erzeugte 48-Bit-Zahl.

      mysql> SELECT UUID();
              -> '6ccd780c-baba-1026-9564-0040f4311e29'

  Beachten Sie, dass `UUID()` noch nicht in Verbindung mit der Replikation funktioniert.

- `VALUES(`col_name`)`

  In einer `INSERT ... ON DUPLICATE KEY UPDATE`-Anweisung können Sie die Funktion `VALUES(`col_name`)` in der `UPDATE`-Klausel verwenden, um Spaltenwerte aus dem `INSERT`-Teil der Anweisung zu referenzieren. Anders gesagt, verweist `VALUES(`col_name`)` in der `UPDATE`-Klausel auf den Wert von `col_name`, der eingefügt worden wäre, wäre nicht ein Konflikt aufgrund einer Schlüsseldublette aufgetreten. Diese Funktion ist insbesondere bei Einfügevorgängen für mehrere Datensätze praktisch. Die Funktion `VALUES()` ist nur sinnvoll in `INSERT ... ON DUPLICATE KEY UPDATE`-Anweisungen zu verwenden; andernfalls gibt sie `NULL` zurück. Abschnitt 13.2.4.3, „`INSERT ... ON DUPLICATE KEY UPDATE`“.

      mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
          -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

## 12.11. Funktionen und Modifizierer für die Verwendung in `GROUP BY`-Klauseln

### 12.11.1. Funktionen zur Benutzung in `GROUP BY`-Klauseln

Dieser Abschnitt beschreibt Gruppenfunktionen (Zusammenfassungsfunktionen), die Wertemengen bearbeiten. Sofern nicht anders angegeben, ignorieren Gruppenfunktionen `NULL`-Werte.

Wenn Sie eine Gruppenfunktion in einer Anweisung verwenden, die keine `GROUP BY`-Klausel enthält, entspricht dies der Gruppierung aller Datensätze.

Die Zusammenfassungsfunktionen `SUM()` und `AVG()` funktionieren bei Zeitwerten nicht. (Sie konvertieren die Werte in Zahlen, wodurch alles, was nach dem ersten nichtnumerischen Zeichen auftaucht, verloren geht.) Um dieses Problem zu umgehen, können Sie die Werte in numerische Einheiten konvertieren, dann die Zusammenfassungsfunktion ausführen und abschließend eine Rückkonvertierung in den Zeitwert durchführen. Ein paar Beispiele:

    SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(time_col))) FROM tbl_name;
    SELECT FROM_DAYS(SUM(TO_DAYS(date_col))) FROM tbl_name;

- `AVG([DISTINCT] `expr`)`

  Gibt den Durchschnittswert von ``expr`` zurück. Die Option `DISTINCT` kann verwendet werden, um den Durchschnitt der unterschiedlichen Werte von `expr` zurückzugeben.

  `AVG()` gibt `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

      mysql> SELECT student_name, AVG(test_score)
          ->        FROM student
          ->        GROUP BY student_name;

- `BIT_AND(`expr`)`

  Gibt das Bit-AND aller Bits in `expr` zurück. Die Berechnung erfolgt mit 64-Bit-Genauigkeit (`BIGINT`-Genauigkeit).

  Die Funktion gibt `18446744073709551615` zurück, wenn keine passenden Datensätze vorhanden waren. (Dies ist der Wert eines vorzeichenlosen `BIGINT`-Werts, bei dem alle Bits gesetzt sind.)

- `BIT_OR(`expr`)`

  Gibt das Bit-OR aller Bits in `expr` zurück. Die Berechnung erfolgt mit 64-Bit-Genauigkeit (`BIGINT`-Genauigkeit).

  Die Funktion gibt `0` zurück, wenn keine passenden Datensätze vorhanden waren.

- `BIT_XOR(`expr`)`

  Gibt das Bit-XOR aller Bits in `expr` zurück. Die Berechnung erfolgt mit 64-Bit-Genauigkeit (`BIGINT`-Genauigkeit).

  Die Funktion gibt `0` zurück, wenn keine passenden Datensätze vorhanden waren.

- `COUNT(`expr`)`

  Gibt die Anzahl der Nicht-`NULL`-Werte in den von einer `SELECT`-Anweisung abgerufenen Datensätzen an.

  `COUNT()` gibt `0` zurück, wenn keine passenden Datensätze vorhanden waren.

      mysql> SELECT student.student_name,COUNT(*)
          ->        FROM student,course
          ->        WHERE student.student_id=course.student_id
          ->        GROUP BY student_name;

  `COUNT(*)` ist dahingehend ein wenig anders, dass es die Anzahl der abgerufenen Datensätze unabhängig davon angibt, ob diese `NULL`-Werte enthält oder nicht.

  `COUNT(*)` ist auf eine sehr schnelle Rückgabe optimiert, wenn die `SELECT`-Anweisung nur Daten aus einer Tabelle abruft, andere Spalten nicht abgerufen werden und keine `WHERE`-Klausel vorhanden ist. Zum Beispiel:

      mysql> SELECT COUNT(*) FROM student;

  Diese Optimierung gilt nur für `MyISAM`-Tabellen, weil eine exakte Datensatzanzahl für diese Speicher-Engine gespeichert wird und so sehr schnell abgerufen werden kann. Bei transaktionssicheren Speicher-Engines wie `InnoDB` und `BDB` ist die Speicherung einer exakten Datensatzanzahl problematischer, weil zum gegebenen Zeitpunkt mehrere Transaktionen stattfinden können, die jede für sich Auswirkungen auf die Anzahl der Datensätze haben kann.

- `COUNT(DISTINCT `expr`,[`expr`...])`

  Gibt die Anzahl unterschiedlicher Nicht-`NULL`-Werte zurück.

  `COUNT(DISTINCT)` gibt `0` zurück, wenn keine passenden Datensätze vorhanden waren.

      mysql> SELECT COUNT(DISTINCT results) FROM student;

  In MySQL können Sie die Anzahl unterschiedlicher Ausdruckskombinationen abrufen, die nicht `NULL` enthalten, indem Sie eine Liste mit Ausdrücken übergeben. In Standard-SQL müssten Sie hierzu eine Verkettung aller Ausdrücke in `COUNT(DISTINCT ...)` angeben.

- `GROUP_CONCAT(`expr`)`

  Diese Funktion gibt einen String als Ergebnis zurück. Dieser gibt die verketteten Nicht-`NULL`-Werte einer Gruppe zurück. `NULL` wird zurückgegeben, wenn keine Nicht-`NULL`-Werte vorhanden sind. Die vollständige Syntax sieht wie folgt aus:

      GROUP_CONCAT([DISTINCT] expr [,expr ...]
                   [ORDER BY {unsigned_integer | col_name | expr}
                       [ASC | DESC] [,col_name ...]]
                   [SEPARATOR str_val])

      mysql> SELECT student_name,
          ->     GROUP_CONCAT(test_score)
          ->     FROM student
          ->     GROUP BY student_name;

  Oder:

      mysql> SELECT student_name,
          ->     GROUP_CONCAT(DISTINCT test_score
          ->               ORDER BY test_score DESC SEPARATOR ' ')
          ->     FROM student
          ->     GROUP BY student_name;

  In MySQL können Sie die verketteten Werte von Ausdruckskombinationen erhalten. Dubletten können Sie mithilfe von `DISTINCT` beseitigen. Wenn Sie Werte im Ergebnis sortieren wollen, sollten Sie eine `ORDER BY`-Klausel verwenden. Um in umgekehrter (absteigender) Reihenfolge zu sortieren, fügen Sie in der `ORDER BY`-Klausel das Schlüsselwort `DESC` zum Namen der Spalte zu, nach der die Sortierung erfolgt: Standardmäßig erfolgt die Sortierung aufsteigend. Dies kann mit dem Schlüsselwort `ASC` explizit festgelegt werden. Auf `SEPARATOR` folgt der String-Wert, der zwischen die Ergebniswerte gesetzt werden soll. Der Vorgabewert ist ein Komma (‘`,`’). Sie können das Trennzeichen vollständig beseitigen, indem Sie `SEPARATOR ''` angeben.

  Sie können mit der Systemvariablen `group_concat_max_len` eine zulässige Maximallänge angeben. (Der Vorgabewert ist 1024.) Um dies zur Laufzeit zu machen, verwenden Sie folgende Syntax (hierbei ist `val` ein vorzeichenloser Integer):

      SET [SESSION | GLOBAL] group_concat_max_len = val;

  Wurde eine Maximallänge eingestellt, dann wird das Ergebnis auf diesen Wert gekürzt.

  Siehe auch `CONCAT()` und `CONCAT_WS()`: Abschnitt 12.3, „String-Funktionen“.

- `MIN([DISTINCT] `expr`)`, `MAX([DISTINCT] `expr`)`

  Gibt den Mindest- bzw. den Höchstwert von `expr` zurück. `MIN()` und `MAX()` können ein String-Argument entgegennehmen; in diesen Fällen geben Sie den niedrigsten bzw. höchsten String-Wert zurück. Siehe auch Abschnitt 7.4.5, „Wie MySQL Indizes benutzt“. Das Schlüsselwort `DISTINCT` können Sie verwenden, um den kleinsten bzw. größten unterschiedlichen Wert im Ausdruck `expr` zu ermitteln; allerdings wird hierbei das gleiche Ergebnis wie beim Weglassen von `DISTINCT` erzielt.

  `MIN()` und `MAX()` geben `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

      mysql> SELECT student_name, MIN(test_score), MAX(test_score)
          ->        FROM student
          ->        GROUP BY student_name;

  Bei `MIN()`, `MAX()` und anderen Zusammenfassungsfunktionen vergleicht MySQL zurzeit `ENUM`- und `SET`-Spalten nach ihrem String-Wert anstelle der relativen Position des Strings in der Menge. Dies unterscheidet sich von der von `ORDER BY` verwendeten Vergleichsmethode. Eine Behebung ist für einen zukünftigen MySQL-Release vorgesehen.

- `STD(`expr`)` `STDDEV(`expr`)`

  Gibt die Populationsstandardabweichung von `expr` zurück. Dies stellt eine Erweiterung des SQL-Standards dar. Die Form `STDDEV()` dieser Funktion ist zum Zweck der Oracle-Kompatibilität vorhanden. Stattdessen kann die SQL-Standardfunktion `STDDEV_POP()` verwendet werden.

  Diese Funktionen geben `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

- `STDDEV_POP(`expr`)`

  Gibt die Populationsstandardabweichung von `expr` (Quadratwurzel von `VAR_POP()`) zurück. Sie können auch `STD()` oder `STDDEV()` verwenden, die äquivalent, aber nicht SQL-Standard sind.

  `STDDEV_POP()` gibt `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

- `STDDEV_SAMP(`expr`)`

  Gibt die Beispielstandardabweichung von `expr` (Quadratwurzel von `VAR_SAMP()`) zurück.

  `STDDEV_SAMP()` gibt `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

- `SUM([DISTINCT] `expr`)`

  Gibt die Summe von `expr` zurück. Wenn die Rückgabemenge keine Datensätze enthält, gibt `SUM()` `NULL` zurück. Das Schlüsselwort `DISTINCT` kann in MySQL 5.1 benutzt werden, um nur die Summe unterschiedlicher Werte in `expr` zu bilden.

  `SUM()` gibt `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

- `VAR_POP(`expr`)`

  Gibt die Populationsstandardvarianz von `expr` zurück. Hierbei werden Datensätze als gesamte Population und nicht als Beispiel betrachtet, d. h., die Anzahl der Datensätze ist der Nenner. Sie können auch `VARIANCE()` verwenden, das äquivalent, aber nicht SQL-Standard ist.

  `VAR_POP()` gibt `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

- `VAR_SAMP(`expr`)`

  Gibt die Beispielvarianz von `expr` zurück. Hieraus ergibt sich, dass der Nenner die Anzahl der Datensätze minus 1 ist.

  `VAR_SAMP()` gibt `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

- `VARIANCE(`expr`)`

  Gibt die Populationsstandardvarianz von `expr` zurück. Dies stellt eine Erweiterung des SQL-Standards dar. Stattdessen kann die SQL-Standardfunktion `VAR_POP()` verwendet werden.

  `VARIANCE()` gibt `NULL` zurück, wenn keine passenden Datensätze vorhanden waren.

### 12.11.2. `GROUP BY`-Modifizierer

Die `GROUP BY`-Klausel gestattet die Verwendung eines Modifizierers `WITH ROLLUP`, der bewirkt, dass zusätzliche Datensätze zur zusammenfassenden Ausgabe hinzugefügt werden. Diese Datensätze stellen Zusammenfassungsoperationen einer höherer Ebene (so genannte Superaggregate) dar. `ROLLUP` gestattet Ihnen auf diese Weise die Beantwortung von Fragen auf mehreren Analyseebenen mit einer einzelnen Abfrage. Es kann beispielsweise verwendet werden, um eine OLAP-Unterstützung (Online Analytical Processing) zu implementieren.

Nehmen wir an, dass in einer Tabelle namens `sales` die Spalten `year`, `country`, `product` und `profit` zur Aufzeichnung der Vertriebsrentabilität vorhanden wären:

    CREATE TABLE sales
    (
        year    INT NOT NULL,
        country VARCHAR(20) NOT NULL,
        product VARCHAR(32) NOT NULL,
        profit  INT
    );

Der Inhalt der Tabelle kann jahresbezogen wie folgt mit einer einfachen `GROUP BY`-Abfrage zusammengefasst werden:

    mysql> SELECT year, SUM(profit) FROM sales GROUP BY year;
    +------+-------------+
    | year | SUM(profit) |
    +------+-------------+
    | 2000 |        4525 |
    | 2001 |        3010 |
    +------+-------------+

Die Ausgabe zeigt die Gesamtrendite pro Jahr an. Wenn Sie aber auch die Rendite für den Gesamtzeitraum bestimmen wollen, müssen Sie die einzelnen Werte selbst hinzufügen oder eine zusätzliche Abfrage ausführen.

Alternativ verwenden Sie `ROLLUP`, wodurch sich die beiden Analyseebenen in einer Abfrage zusammenfassen lassen. Das Hinzufügen eines `WITH ROLLUP`-Modifizierers zur `GROUP BY`-Klausel bewirkt, dass die Abfrage einen anderen Datensatz erstellt, der die Endsumme über alle vier Jahre angibt:

    mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;
    +------+-------------+
    | year | SUM(profit) |
    +------+-------------+
    | 2000 |        4525 |
    | 2001 |        3010 |
    | NULL |        7535 |
    +------+-------------+

Die Super-Aggregat-Zeile, die die Endsumme zusammenfasst, lässt sich am Wert `NULL` in der Spalte `year` erkennen.

Die Wirkung von `ROLLUP` ist etwas komplexer, wenn mehrere `GROUP BY`-Klauseln vorhanden sind. In diesem Fall erzeugt die Abfrage jedes Mal, wenn eine „Unterbrechung“ (also eine Wertänderung) in einer beliebigen Spalte (mit Ausnahme der letzten Gruppenspalte) vorhanden ist, einen Super-Aggregat-Datensatz.

So könnte etwa ohne `ROLLUP` eine Zusammenfassung der Tabelle `sales` basierend auf `year`, `country` und `product` wie folgt aussehen:

    mysql> SELECT year, country, product, SUM(profit)
        -> FROM sales
        -> GROUP BY year, country, product;
    +------+---------+------------+-------------+
    | year | country | product    | SUM(profit) |
    +------+---------+------------+-------------+
    | 2000 | Finland | Computer   |        1500 |
    | 2000 | Finland | Phone      |         100 |
    | 2000 | India   | Calculator |         150 |
    | 2000 | India   | Computer   |        1200 |
    | 2000 | USA     | Calculator |          75 |
    | 2000 | USA     | Computer   |        1500 |
    | 2001 | Finland | Phone      |          10 |
    | 2001 | USA     | Calculator |          50 |
    | 2001 | USA     | Computer   |        2700 |
    | 2001 | USA     | TV         |         250 |
    +------+---------+------------+-------------+

Die Ausgabe zeigt Zusammenfassungswerte nur auf der Jahres-, Länder- und/oder Produktebene der Analyse an. Wird nun `ROLLUP` hinzugefügt, dann erzeugt die Abfrage diverse zusätzliche Datensätze:

    mysql> SELECT year, country, product, SUM(profit)
        -> FROM sales
        -> GROUP BY year, country, product WITH ROLLUP;
    +------+---------+------------+-------------+
    | year | country | product    | SUM(profit) |
    +------+---------+------------+-------------+
    | 2000 | Finland | Computer   |        1500 |
    | 2000 | Finland | Phone      |         100 |
    | 2000 | Finland | NULL       |        1600 |
    | 2000 | India   | Calculator |         150 |
    | 2000 | India   | Computer   |        1200 |
    | 2000 | India   | NULL       |        1350 |
    | 2000 | USA     | Calculator |          75 |
    | 2000 | USA     | Computer   |        1500 |
    | 2000 | USA     | NULL       |        1575 |
    | 2000 | NULL    | NULL       |        4525 |
    | 2001 | Finland | Phone      |          10 |
    | 2001 | Finland | NULL       |          10 |
    | 2001 | USA     | Calculator |          50 |
    | 2001 | USA     | Computer   |        2700 |
    | 2001 | USA     | TV         |         250 |
    | 2001 | USA     | NULL       |        3000 |
    | 2001 | NULL    | NULL       |        3010 |
    | NULL | NULL    | NULL       |        7535 |
    +------+---------+------------+-------------+

Bei dieser Abfrage bewirkt das Hinzufügen von `ROLLUP`, dass die Ausgabe Zusammenfassungsinformationen auf vier Analyseebenen (und nicht nur auf einer) enthält. Die Ausgabe von `ROLLUP` interpretieren Sie wie folgt:

- Auf jede Menge von Produktdatensätzen für ein gegebenes Jahr und Land folgend wird ein zusätzlicher Datensatz erzeugt, der die Gesamtzahl aller Produkte angibt. Bei diesen Datensätzen ist die Spalte `product` auf `NULL` gesetzt.

- Auf jede Menge von Datensätzen für ein gegebenes Jahr und Land folgend wird ein zusätzlicher Datensatz erzeugt, der die Endsumme für alle Länder und Produkte angibt. Bei diesen Datensätzen sind die Spalten `country` und `products` auf `NULL` gesetzt.

- Abschließend wird auf alle anderen Datensätze folgend ein zusätzlicher zusammenfassender Datensatz erzeugt, der die Endsumme für alle Jahre, Länder und Produkte angibt. Bei diesem Datensatz sind die Spalten `year`, `country` und `products` auf `NULL` gesetzt.

Weitere Aspekte der Benutzung von `ROLLUP`

Die folgenden Punkte beschreiben einige für die MySQL-Implementierung von `ROLLUP` spezifischen Verhaltensweisen:

Wenn Sie `ROLLUP` verwenden, dürfen Sie nicht gleichzeitig auch eine `ORDER BY`-Klausel zur Sortierung der Ergebnisse einsetzen. Mit anderen Worten, `ROLLUP` und `ORDER BY` schließen sich gegenseitig aus. Trotzdem können Sie Einfluss auf die Sortierreihenfolge nehmen. `GROUP BY` sortiert in MySQL Ergebnisse, und Sie können die Schlüsselwörter `ASC` und `DESC` ausdrücklich für Spaltennamen in der `GROUP BY`-Liste angeben, um die Sortierfolge für einzelne Spalten zu spezifizieren. (Die von `ROLLUP` hinzugefügten Zusammenfassungsdatensätze höherer Ebene erscheinen ungeachtet der Sortierfolge trotzdem erst hinter den Datensätzen, aus denen sie berechnet wurden.)

Mit `LIMIT` können Sie die Anzahl der an den Client zurückgegebenen Datensätze beschränken. `LIMIT` wird nach `ROLLUP` angewendet, d. h., die Beschränkung betrifft auch die zusätzlichen Datensätze, die von `ROLLUP` hinzugefügt worden sind. Zum Beispiel:

    mysql> SELECT year, country, product, SUM(profit)
        -> FROM sales
        -> GROUP BY year, country, product WITH ROLLUP
        -> LIMIT 5;
    +------+---------+------------+-------------+
    | year | country | product    | SUM(profit) |
    +------+---------+------------+-------------+
    | 2000 | Finland | Computer   |        1500 |
    | 2000 | Finland | Phone      |         100 |
    | 2000 | Finland | NULL       |        1600 |
    | 2000 | India   | Calculator |         150 |
    | 2000 | India   | Computer   |        1200 |
    +------+---------+------------+-------------+

Die Verwendung von `LIMIT` mit `ROLLUP` kann Ergebnisse erzeugen, die schwieriger zu interpretieren sind, weil Sie weniger Kontext haben, um die Super-Aggregate zu verstehen.

Die `NULL`-Indikatoren in jedem Super-Aggregat-Datensatz werden erzeugt, wenn der Datensatz an den Client gesendet wird. Der Server prüft alle in der `GROUP BY`-Klausel genannten Spalten, die auf die erste (am weitesten links stehende) Spalte folgen, deren Wert geändert wurde. Bei jeder Spalte in der Ergebnismenge, deren Name lexikalisch mit einem dieser Namen übereinstimmt, wird der Wert auf `NULL` gesetzt. (Wenn Sie Gruppenspalten über die Spaltennummer angeben, identifiziert der Server die auf `NULL` zu setzenden Spalten anhand ihrer Nummer.)

Weil die `NULL`-Werte in den Super-Aggregat-Datensätzen als solche während der Abfrageverarbeitung relativ spät in das Ergebnis eingefügt werden, können Sie sie nicht wie `NULL`-Werte innerhalb der Abfrage selbst überprüfen. So können Sie beispielsweise `HAVING product IS NULL` nicht zur Abfrage hinzufügen, um alle Datensätze mit Ausnahme der Super-Aggregat-Datensätze aus der Ausgabe zu entfernen.

Andererseits erscheinen die `NULL`-Werte als `NULL` auf der Clientseite und können insofern mithilfe einer beliebigen MySQL-Clientprogrammierschnittstelle geprüft werden.

### 12.11.3. `GROUP BY` mit versteckten Feldern

MySQL erweitert die Verwendung von `GROUP BY` dahingehend, dass Sie Spalten oder Berechnungen in der `SELECT`-Liste verwenden können, die nicht in der `GROUP BY`-Klausel erscheinen. Dies steht für „ein beliebiger Wert für diese Gruppe“. Sie können die Leistung dadurch optimieren, dass Sie das Sortieren und Gruppieren unnötiger Elemente umgehen. So müssen Sie beispielsweise in der folgenden Abfrage keine Gruppierung von `customer.name` durchführen:

    SELECT order.custid, customer.name, MAX(payments)
      FROM order,customer
      WHERE order.custid = customer.custid
      GROUP BY order.custid;

In Standard-SQL hätten Sie hier `customer.name` zur `GROUP BY`-Klausel hinzufügen müssen. In MySQL ist der Name redundant, wenn bei der Ausführung der SQL-Modus `ONLY_FULL_GROUP_BY` nicht aktiviert ist.

Verwenden Sie diese Funktion nicht, wenn die Spalten, die Sie im `GROUP BY`-Anteil weglassen, in der Gruppe nicht eindeutig sind! Sie erhalten ansonsten nicht vorhersehbare Ergebnisse.

In manchen Fällen können Sie mit `MIN()` und `MAX()` einen bestimmten Spaltenwert auch dann erhalten, wenn dieser nicht eindeutig ist. Folgendes übergibt den Wert von `column` aus dem Datensatz, der den niedrigsten Wert in der Spalte `sort` hat:

    SUBSTR(MIN(CONCAT(RPAD(sort,6,' '),column)),7)

Siehe auch Abschnitt 3.6.4, „Die Zeilen, die das gruppenweise Maximum eines bestimmten Felds enthalten“.

Beachten Sie, dass Sie, wenn Sie sich an den SQL-Standard halten wollen, Ausdrücke nicht in `GROUP BY`-Klauseln verwenden dürfen. Sie können diese Einschränkung umgehen, indem Sie ein Alias für den Ausdruck verwenden:

    SELECT id,FLOOR(value/100) AS val
      FROM tbl_name
      GROUP BY id, val;

MySQL gestattet hingegen die Benutzung von Ausdrücken in `GROUP BY`-Klauseln. Zum Beispiel:

    SELECT id,FLOOR(value/100)
      FROM tbl_name
      GROUP BY id, FLOOR(value/100);

Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.

Zurück |  | Weiter
Kapitel 11. Datentypen | Zum Anfang | Kapitel 13. SQL-Anweisungssyntax