Dieser Abschnitt zeigt Beispiele für die Ergebnisse von Anfragen mit Präzisionsberechnungen in MySQL 5.1.
Beispiel 1. Zahlen werden möglichst mit ihrem genauen Wert wie vorgegeben benutzt:
mysql> SELECT .1 + .2 = .3;
+--------------+
| .1 + .2 = .3 |
+--------------+
|            1 |
+--------------+
Bei Fließkommawerten sind die Ergebnisse Näherungen:
mysql> SELECT .1E0 + .2E0 = .3E0;
+--------------------+
| .1E0 + .2E0 = .3E0 |
+--------------------+
|                  0 |
+--------------------+
      Eine andere Möglichkeit, den Unterschied in der Behandlung von
      genauen und Näherungswerten zu zeigen, besteht darin, eine kleine
      Zahl immer wieder zu einer Summe zu addieren. Betrachten Sie
      folgende gespeicherte Prozedur, die zu einer Variablen tausendmal
      den Wert .0001 addiert.
    
CREATE PROCEDURE p ()
BEGIN
  DECLARE i INT DEFAULT 0;
  DECLARE d DECIMAL(10,4) DEFAULT 0;
  DECLARE f FLOAT DEFAULT 0;
  WHILE i < 10000 DO
    SET d = d + .0001;
    SET f = f + .0001E0;
    SET i = i + 1;
  END WHILE;
  SELECT d, f;
END;
      Logischerweise sollte die Summe für d und
      f beide Male 1 ergeben, aber in Wirklichkeit
      ist dies nur bei der Dezimalberechnung der Fall. In der
      Fließkommaberechnung wird ein Fehler eingeführt:
    
+--------+------------------+ | d | f | +--------+------------------+ | 1.0000 | 0.99999999999991 | +--------+------------------+
      Beispiel 2. Multiplikationen
      werden mit der durch den SQL-Standard vorgegebenen Anzahl
      Dezimalstellen ausgeführt: Für zwei Zahlen
      X1 und X2,
      die S1 beziehungsweise
      S2 Dezimalstellen haben, entsteht ein
      Ergebnis mit S1 +
      S2
mysql> SELECT .01 * .01;
+-----------+
| .01 * .01 |
+-----------+
| 0.0001    |
+-----------+
Beispiel 3. Das Rundungsverhalten ist wohldefiniert:
      So ist das Rundungsverhalten (beispielsweise der Funktion
      ROUND()) unabhängig von der Implementierung
      der zugrunde liegenden C-Bibliothek, sodass die Ergebnisse
      plattformübergreifend konsistent sind.
    
      DECIMAL-Spalten und genaue Zahlen werden nach
      der Regel „Ab der Hälfte wird aufgerundet“
      behandelt: Werte mit einem Dezimalteil von .5 oder mehr werden,
      wie das nächste Beispiel zeigt, immer von null weg auf den
      nächstgelegenen Integer aufgerundet:
    
mysql> SELECT ROUND(2.5), ROUND(-2.5);
+------------+-------------+
| ROUND(2.5) | ROUND(-2.5) |
+------------+-------------+
| 3          | -3          |
+------------+-------------+
Dagegen stützt sich die Rundung von Fließkommawerten auf die C-Bibliothek, die auf vielen Systemen nach dem Grundsatz „Runde auf die nächste gerade Zahl“ verfährt. Auf solchen Systemen werden Werte mit einem Bruchteilsanteil auf die nächste gerade Zahl gerundet:
mysql> SELECT ROUND(2.5E0), ROUND(-2.5E0);
+--------------+---------------+
| ROUND(2.5E0) | ROUND(-2.5E0) |
+--------------+---------------+
|            2 |            -2 |
+--------------+---------------+
Beispiel 4. Wenn Sie im Strict-Modus einen zu großen Wert einfügen, führt dies zu einem Überlauf und verursacht einen Fehler. Der Wert wird nicht auf ein zulässiges Maß zurechtgestutzt.
Läuft MySQL jedoch nicht im Strict-Modus, wird der Wert abgeschnitten, bis er passt:
mysql>SET sql_mode='';Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t (i TINYINT);Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO t SET i = 128;Query OK, 1 row affected, 1 warning (0.00 sec) mysql>SELECT i FROM t;+------+ | i | +------+ | 127 | +------+ 1 row in set (0.00 sec)
Immerhin wird eine Überlaufbedingung registriert, wenn der Strict-Modus eingeschaltet ist:
mysql>SET sql_mode='STRICT_ALL_TABLES';Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t (i TINYINT);Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 128;ERROR 1264 (22003): Out of range value adjusted for column 'i' at row 1 mysql>SELECT i FROM t;Empty set (0.00 sec)
      Beispiel 5: Sind der Strict-Modus
      und ERROR_FOR_DIVISION_BY_ZERO eingeschaltet,
      verursacht eine Division durch null einen Fehler, anstatt das
      Ergebnis NULL nach sich zu ziehen.
    
      Im nichtstrikten Modus hat die Division durch null das Ergebnis
      NULL:
    
mysql>SET sql_mode='';Query OK, 0 rows affected (0.01 sec) mysql>CREATE TABLE t (i TINYINT);Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 1 / 0;Query OK, 1 row affected (0.00 sec) mysql>SELECT i FROM t;+------+ | i | +------+ | NULL | +------+ 1 row in set (0.03 sec)
Sind jedoch die richtigen SQL-Modi eingeschaltet, verursacht eine Division durch null immer einen Fehler:
mysql>SET sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t (i TINYINT);Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 1 / 0;ERROR 1365 (22012): Division by 0 mysql>SELECT i FROM t;Empty set (0.01 sec)
Beispiel 6. Vor MySQL 5.0.3 (also vor der Einführung von Präzisionsberechnungen) wurden sowohl genaue als auch näherungsweise Literale in Fließkommazahlen mit doppelter Genauigkeit umgewandelt:
mysql>SELECT VERSION();+------------+ | VERSION() | +------------+ | 4.1.18-log | +------------+ 1 row in set (0.01 sec) mysql>CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;Query OK, 1 row affected (0.07 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>DESCRIBE t;+-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | a | double(3,1) | | | 0.0 | | | b | double | | | 0 | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.04 sec)
      Seit MySQL 5.0.3 werden näherungsweise Literale zwar immer noch
      in Fließkommazahlen konvertiert, genaue hingegen werden als
      DECIMAL behandelt:
    
mysql>SELECT VERSION();+-----------------+ | VERSION() | +-----------------+ | 5.1.6-alpha-log | +-----------------+ 1 row in set (0.11 sec) mysql>CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>DESCRIBE t;+-------+-----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-----------------------+------+-----+---------+-------+ | a | decimal(2,1) unsigned | NO | | 0.0 | | | b | double | NO | | 0 | | +-------+-----------------------+------+-----+---------+-------+ 2 rows in set (0.01 sec)
Beispiel 7. Wenn das Argument einer Aggregatfunktion ein genauer numerischer Typ ist, ist ihr Ergebnis ebenfalls ein genauer numerischer Typ, und zwar mit mindestens so vielen Dezimalstellen, wie das Argument hatte.
Betrachten Sie folgende Anweisungen:
mysql>CREATE TABLE t (i INT, d DECIMAL, f FLOAT);mysql>INSERT INTO t VALUES(1,1,1);mysql>CREATE TABLE y SELECT AVG(i), AVG(d), AVG(f) FROM t;
Vor MySQL 5.0.3 (also vor der Einführung von Präzisionsberechnungen in MySQL) sähe das Ergebnis folgendermaßen aus:
mysql> DESCRIBE y;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| AVG(i) | double(17,4) | YES  |     | NULL    |       |
| AVG(d) | double(17,4) | YES  |     | NULL    |       |
| AVG(f) | double       | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
Das Resultat ist ein Double-Wert, egal welchen Typ das Argument hatte.
Mit MySQL 5.0.3 hat sich dies geändert:
mysql> DESCRIBE y;
+--------+---------------+------+-----+---------+-------+
| Field  | Type          | Null | Key | Default | Extra |
+--------+---------------+------+-----+---------+-------+
| AVG(i) | decimal(14,4) | YES  |     | NULL    |       |
| AVG(d) | decimal(14,4) | YES  |     | NULL    |       |
| AVG(f) | double        | YES  |     | NULL    |       |
+--------+---------------+------+-----+---------+-------+
Hier entsteht nur für das Fließkommaargument ein Ergebnis vom Typ Double. Argumente mit genauen Typen haben genaue Ergebnisse.
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.

