Di MySQL, VALUES
pernyataan mengembalikan satu set satu atau lebih baris sebagai tabel. Pada dasarnya, ini adalah konstruktor nilai tabel sesuai dengan standar SQL, yang juga berfungsi sebagai pernyataan SQL mandiri.
VALUES
pernyataan diperkenalkan di MySQL 8.0.19.
Sintaks
Sintaks resminya seperti ini:
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
Contoh
Berikut adalah contoh sederhana untuk mendemonstrasikan cara kerjanya:
VALUES ROW(1, 2, 3), ROW(4, 5, 6);
Hasil:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Kolom yang dihasilkan secara implisit bernama column_0
, column_1
, column_2
, dan seterusnya, selalu diawali dengan 0
.
Kita dapat melihat bahwa setiap ROW()
klausa konstruktor baris menghasilkan baris baru di tabel yang dihasilkan.
Setiap ROW()
berisi daftar nilai dari satu atau lebih nilai skalar yang diapit dalam tanda kurung. Nilai dapat berupa literal dari semua tipe data MySQL atau ekspresi yang diubah menjadi nilai skalar.
Oleh karena itu, kita juga dapat melakukan hal berikut:
VALUES ROW("Black", "Cat"), ROW("Yellow", "Dog");
Hasil:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Atau hal-hal seperti ini:
VALUES
ROW(CURDATE(), DATE_ADD(CURDATE(), INTERVAL 10 YEAR)),
ROW(CURTIME(), DATE_ADD(CURTIME(), INTERVAL 2 HOUR));
Hasil:
+---------------------+---------------------+ | 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 | +---------------------+---------------------+
The ORDER BY
Klausa
Sintaksnya memungkinkan penggunaan ORDER BY
klausa untuk mengurutkan hasil. Namun, saya menemukan bahwa ORDER BY
klausa tidak berfungsi seperti yang diharapkan pada sistem yang saya coba jalankan.
Begini seharusnya work (menurut dokumentasi MySQL):
VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1;
Hasil:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | -2 | 3 | | 4 | 6 | 8 | | 5 | 7 | 9 | +----------+----------+----------+
Tetapi pada dua sistem yang saya menentang pernyataan itu (MySQL 8.0.26 di Ubuntu 20.04.3 dan MySQL 8.0.27 Homebrew di MacOS Monterery), ORDER BY
klausa tidak berfungsi sama sekali. Mungkin ini bug.
LIMIT
Klausa
Kita dapat menggunakan LIMIT
klausa untuk membatasi jumlah baris yang dihasilkan:
VALUES
ROW('Black', 'Cat'),
ROW('Yellow', 'Dog'),
ROW('Aqua', 'Fish')
LIMIT 2;
Hasil:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | Black | Cat | | Yellow | Dog | +----------+----------+
Dengan SELECT
Pernyataan
Kami juga dapat menggunakan VALUES
pernyataan dalam SELECT
pernyataan, seolah-olah VALUES
konstruktor tabel adalah tabel yang sebenarnya:
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;
Hasil:
+---------+---------+ | PetName | PetType | +---------+---------+ | Bark | Dog | +---------+---------+
ROW()
Tidak Boleh Kosong
Konstruktor baris tidak boleh kosong, kecuali jika digunakan sebagai sumber dalam INSERT
penyataan.
Inilah yang terjadi jika kita mencoba menggunakan konstruktor baris kosong:
VALUES ROW();
Hasil:
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()
Dapat Berisi Nilai Null
Meskipun konstruktor baris tidak boleh kosong, mereka dapat berisi nilai Null:
VALUES ROW(null, null);
Hasil:
+----------+----------+ | column_0 | column_1 | +----------+----------+ | NULL | NULL | +----------+----------+
Setiap ROW()
Harus Mengandung Jumlah Nilai yang Sama
Setiap ROW()
dalam VALUES
yang sama pernyataan harus memiliki jumlah nilai yang sama dalam daftar nilainya.
Oleh karena itu, kami tidak dapat melakukan ini:
VALUES ROW(1, 2), ROW(3);
Hasil:
ERROR 1136 (21S01): Column count doesn't match value count at row 2
Menggunakan VALUES
untuk Memasukkan Data
Kita dapat menggunakan VALUES
pernyataan bersama dengan INSERT
dan REPLACE
pernyataan untuk memasukkan data ke dalam tabel.
Contoh:
INSERT INTO Pets VALUES
ROW(9, 3, 1, 'Woof', '2020-10-03'),
ROW(10, 4, 5, 'Ears', '2022-01-11');
Itu memasukkan dua baris ke dalam tabel yang disebut Pets
. Ini mengasumsikan bahwa tabel sudah ada.
Sekarang kita dapat menggunakan SELECT
pernyataan untuk melihat nilai baru dalam tabel:
SELECT * FROM Pets
WHERE PetId IN (9, 10);
Hasil:
+-------+-----------+---------+---------+------------+ | PetId | PetTypeId | OwnerId | PetName | DOB | +-------+-----------+---------+---------+------------+ | 9 | 3 | 1 | Woof | 2020-10-03 | | 10 | 4 | 5 | Ears | 2022-01-11 | +-------+-----------+---------+---------+------------+
INSERT
di atas pernyataan ini setara dengan melakukan hal berikut:
INSERT INTO Pets VALUES
(9, 3, 1, 'Woof', '2020-10-03'),
(10, 4, 5, 'Ears', '2022-01-11');
Saat Membuat Tabel
VALUES
pernyataan juga dapat digunakan sebagai pengganti tabel sumber di CREATE TABLE … SELECT
dan CREATE VIEW … SELECT
pernyataan.
Ini contohnya:
CREATE TABLE t1 VALUES ROW(1,2,3), ROW(4,5,6);
SELECT * FROM t1;
Hasil:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Kita juga bisa melakukan ini:
CREATE TABLE t2 SELECT * FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS v;
SELECT * FROM t2;
Hasil:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Kedua CREATE TABLE
pernyataan seperti melakukan ini:
CREATE TABLE t3 SELECT * FROM t2;
SELECT * FROM t3;
Hasil:
+----------+----------+----------+ | column_0 | column_1 | column_2 | +----------+----------+----------+ | 1 | 2 | 3 | | 4 | 5 | 6 | +----------+----------+----------+
Dalam hal ini, saya menggunakan t2
tabel sebagai tabel sumber, alih-alih memberikan nilai dalam VALUES
pernyataan.