In MySQL sind die VALUES
-Anweisung gibt eine Menge von einer oder mehreren Zeilen als Tabelle zurück. Im Grunde ist es ein Tabellenwertkonstruktor nach dem SQL-Standard, der auch als eigenständiges SQL-Statement funktioniert.
Die VALUES
-Anweisung wurde in MySQL 8.0.19 eingeführt.
Syntax
Die offizielle Syntax lautet wie folgt:
VALUES row_constructor_list [ORDER BY column_designator] [LIMIT number]
row_constructor_list:
ROW(value_list)[, ROW(value_list)][, ...]
value_list:
value[, value][, ...]
column_designator:
column_index
Beispiel
Hier ist ein einfaches Beispiel, um zu demonstrieren, wie es funktioniert:
VALUES ROW(1, 2, 3), ROW(4, 5, 6);
Ergebnis:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Die resultierenden Spalten heißen implizit column_0
, column_1
, column_2
, und so weiter, immer beginnend mit 0
.
Wir können sehen, dass jede ROW()
Zeilenkonstruktorklausel führt zu einer neuen Zeile in der resultierenden Tabelle.
Jede ROW()
enthält eine Werteliste mit einem oder mehreren Skalarwerten, die in Klammern eingeschlossen sind. Ein Wert kann ein Literal eines beliebigen MySQL-Datentyps oder ein Ausdruck sein, der in einen Skalarwert aufgelöst wird.
Daher können wir auch Folgendes tun:
VALUES ROW("Black", "Cat"), ROW("Yellow", "Dog");
Ergebnis:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Oder solche Sachen:
VALUES
ROW(CURDATE(), DATE_ADD(CURDATE(), INTERVAL 10 YEAR)),
ROW(CURTIME(), DATE_ADD(CURTIME(), INTERVAL 2 HOUR));
Ergebnis:
+---------------------+---------------------+ | column_0 | column_1 | +---------------------+---------------------+ | 2022-02-17 00:00:00 | 2032-02-17 00:00:00 | | 2022-02-17 09:30:46 | 2022-02-17 11:30:46 | +---------------------+---------------------+
Der ORDER BY
Klausel
Die Syntax erlaubt die Verwendung des ORDER BY
Klausel, um die Ergebnisse zu ordnen. Ich habe jedoch festgestellt, dass der ORDER BY
-Klausel funktioniert auf den Systemen, auf denen ich versucht habe, sie auszuführen, nicht wie erwartet.
Hier ist, wie es sollte funktioniert (laut MySQL-Dokumentation):
VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1;
Ergebnis:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | -2 | 3 | | 4 | 6 | 8 | | 5 | 7 | 9 | +----------+----------+----------+
Aber auf den beiden Systemen, auf denen ich diese Anweisung ausgeführt habe (MySQL 8.0.26 auf Ubuntu 20.04.3 und MySQL 8.0.27 Homebrew auf MacOS Monterery), ist die ORDER BY
Klausel geht gar nicht. Vielleicht ist das ein Fehler.
Das LIMIT
Klausel
Wir können das LIMIT
verwenden -Klausel, um die Anzahl der ausgegebenen Zeilen zu begrenzen:
VALUES
ROW('Black', 'Cat'),
ROW('Yellow', 'Dog'),
ROW('Aqua', 'Fish')
LIMIT 2;
Ergebnis:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Mit einem SELECT
Erklärung
Wir können auch die VALUES
verwenden -Anweisung innerhalb eines SELECT
Anweisung, als ob die VALUES
Tabellenkonstruktor wäre eine tatsächliche Tabelle:
SELECT
PetName,
PetType
FROM
(VALUES
ROW(1, "Fluffy", "Cat"),
ROW(2, "Bark", "Dog"),
ROW(3, "Gallop", "Horse")
) AS Pets(PetId, PetName, PetType)
WHERE PetId = 2;
Ergebnis:
+---------+---------+ | PetName | PetType | +---------+---------+ | Bark | Dog | +---------+---------+
ROW()
Darf nicht leer sein
Ein Zeilenkonstruktor darf nicht leer sein, es sei denn, er wird als Quelle in einem INSERT
verwendet Erklärung.
Folgendes passiert, wenn wir versuchen, einen leeren Zeilenkonstruktor zu verwenden:
VALUES ROW();
Ergebnis:
ERROR 3942 (HY000): Each row of a VALUES clause must have at least one column, unless when used as source in an INSERT statement.
ROW()
Kann Nullwerte enthalten
Obwohl Zeilenkonstruktoren nicht leer sein können, können sie Nullwerte enthalten:
VALUES ROW(null, null);
Ergebnis:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | NULL | NULL | +----------+----------+
Jede ROW()
Muss die gleiche Anzahl von Werten enthalten
Jede ROW()
in denselben VALUES
-Anweisung muss die gleiche Anzahl von Werten in ihrer Werteliste haben.
Daher können wir Folgendes nicht tun:
VALUES ROW(1, 2), ROW(3);
Ergebnis:
ERROR 1136 (21S01): Column count doesn't match value count at row 2
Verwendung von VALUES
zum Einfügen von Daten
Wir können die VALUES
verwenden -Anweisung in Verbindung mit INSERT
und REPLACE
Anweisungen zum Einfügen von Daten in eine Tabelle.
Beispiel:
INSERT INTO Pets VALUES
ROW(9, 3, 1, 'Woof', '2020-10-03'),
ROW(10, 4, 5, 'Ears', '2022-01-11');
Dadurch wurden zwei Zeilen in eine Tabelle namens Pets
eingefügt . Dies setzt voraus, dass die Tabelle bereits existiert.
Wir können jetzt ein SELECT
verwenden -Anweisung, um die neuen Werte in der Tabelle anzuzeigen:
SELECT * FROM Pets
WHERE PetId IN (9, 10);
Ergebnis:
+-------+-----------+---------+---------+------------+ | PetId | PetTypeId | OwnerId | PetName | DOB | +-------+-----------+---------+---------+------------+ | 9 | 3 | 1 | Woof | 2020-10-03 | | 10 | 4 | 5 | Ears | 2022-01-11 | +-------+-----------+---------+---------+------------+
Das obige INSERT
-Anweisung ist das Äquivalent zu Folgendem:
INSERT INTO Pets VALUES
(9, 3, 1, 'Woof', '2020-10-03'),
(10, 4, 5, 'Ears', '2022-01-11');
Beim Erstellen von Tabellen
Die VALUES
-Anweisung kann auch anstelle der Quelltabelle in CREATE TABLE … SELECT
verwendet werden und CREATE VIEW … SELECT
Aussagen.
Hier ist ein Beispiel:
CREATE TABLE t1 VALUES ROW(1,2,3), ROW(4,5,6);
SELECT * FROM t1;
Ergebnis:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Wir können dies auch tun:
CREATE TABLE t2 SELECT * FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS v;
SELECT * FROM t2;
Ergebnis:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Diese beiden CREATE TABLE
Anweisungen sind wie folgt:
CREATE TABLE t3 SELECT * FROM t2;
SELECT * FROM t3;
Ergebnis:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
In diesem Fall habe ich den t2
verwendet table als Quelltabelle, anstatt die Werte in einem VALUES
bereitzustellen Aussage.