Mysql
 sql >> Database >  >> RDS >> Mysql

Dichiarazione VALUES in MySQL

In MySQL, i VALUES istruzione restituisce un insieme di una o più righe come tabella. Fondamentalmente, è un costruttore di valori di tabella in conformità con lo standard SQL, che funziona anche come un'istruzione SQL autonoma.

I VALUES istruzione è stata introdotta in MySQL 8.0.19.

Sintassi

La sintassi ufficiale è questa:

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

Esempio

Ecco un semplice esempio per dimostrare come funziona:

VALUES ROW(1, 2, 3), ROW(4, 5, 6);

Risultato:

+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |        2 |        3 |
|        4 |        5 |        6 |
+----------+----------+----------+

Le colonne risultanti sono implicitamente denominate column_0 , column_1 , column_2 , e così via, iniziando sempre con 0 .

Possiamo vedere che ogni ROW() La clausola del costruttore di riga genera una nuova riga nella tabella risultante.

Ogni ROW() contiene un elenco di valori di uno o più valori scalari racchiusi tra parentesi. Un valore può essere un valore letterale di qualsiasi tipo di dati MySQL o un'espressione che si risolve in un valore scalare.

Pertanto possiamo anche fare quanto segue:

VALUES ROW("Black", "Cat"), ROW("Yellow", "Dog");

Risultato:

+----------+----------+
| column_0 | column_1 |
+----------+----------+
| Black    | Cat      |
| Yellow   | Dog      |
+----------+----------+

O cose come questa:

VALUES 
   ROW(CURDATE(), DATE_ADD(CURDATE(), INTERVAL 10 YEAR)),
   ROW(CURTIME(), DATE_ADD(CURTIME(), INTERVAL 2 HOUR));

Risultato:

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

Il ORDER BY Clausola

La sintassi consente l'utilizzo di ORDER BY clausola per ordinare i risultati. Tuttavia, ho scoperto che il ORDER BY La clausola non funziona come previsto sui sistemi su cui ho provato a eseguirla.

Ecco come dovrebbe lavoro (secondo la documentazione MySQL):

VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1;

Risultato:

+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |       -2 |        3 |
|        4 |        6 |        8 |
|        5 |        7 |        9 |
+----------+----------+----------+

Ma sui due sistemi su cui ho eseguito quell'istruzione (MySQL 8.0.26 su Ubuntu 20.04.3 e MySQL 8.0.27 Homebrew su MacOS Monterery), il ORDER BY la clausola non funziona affatto. Forse questo è un bug.

Il LIMIT Clausola

Possiamo usare il LIMIT clausola per limitare il numero di righe che vengono emesse:

VALUES 
   ROW('Black', 'Cat'), 
   ROW('Yellow', 'Dog'), 
   ROW('Aqua', 'Fish')
LIMIT 2;

Risultato:

+----------+----------+
| column_0 | column_1 |
+----------+----------+
| Black    | Cat      |
| Yellow   | Dog      |
+----------+----------+

Con un SELECT Dichiarazione

Possiamo anche usare i VALUES istruzione all'interno di un SELECT istruzione, come se il VALUES costruttore di tabelle erano una tabella reale:

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;

Risultato:

+---------+---------+
| PetName | PetType |
+---------+---------+
| Bark    | Dog     |
+---------+---------+

ROW() Non può essere vuoto

Un costruttore di riga non può essere vuoto, a meno che non venga utilizzato come origine in un INSERT dichiarazione.

Ecco cosa succede se proviamo a utilizzare un costruttore di righe vuoto:

VALUES ROW();

Risultato:

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() Può contenere valori nulli

Sebbene i costruttori di riga non possano essere vuoti, possono contenere valori Null:

VALUES ROW(null, null);

Risultato:

+----------+----------+
| column_0 | column_1 |
+----------+----------+
|     NULL |     NULL |
+----------+----------+

Ogni ROW() Deve contenere lo stesso numero di valori

Ogni ROW() nello stesso VALUES l'istruzione deve avere lo stesso numero di valori nella sua lista valori.

Pertanto, non possiamo farlo:

VALUES ROW(1, 2), ROW(3);

Risultato:

ERROR 1136 (21S01): Column count doesn't match value count at row 2

Utilizzo di VALUES per inserire dati

Possiamo usare i VALUES istruzione insieme a INSERT e REPLACE istruzioni per inserire dati in una tabella.

Esempio:

INSERT INTO Pets VALUES 
   ROW(9, 3, 1, 'Woof', '2020-10-03'), 
   ROW(10, 4, 5, 'Ears', '2022-01-11');

Che ha inserito due righe in una tabella chiamata Pets . Ciò presuppone che la tabella esista già.

Ora possiamo usare un SELECT istruzione per vedere i nuovi valori nella tabella:

SELECT * FROM Pets
WHERE PetId IN (9, 10);

Risultato:

+-------+-----------+---------+---------+------------+
| PetId | PetTypeId | OwnerId | PetName | DOB        |
+-------+-----------+---------+---------+------------+
|     9 |         3 |       1 | Woof    | 2020-10-03 |
|    10 |         4 |       5 | Ears    | 2022-01-11 |
+-------+-----------+---------+---------+------------+

Quanto sopra INSERT istruzione equivale a fare quanto segue:

INSERT INTO Pets VALUES 
   (9, 3, 1, 'Woof', '2020-10-03'), 
   (10, 4, 5, 'Ears', '2022-01-11');

Quando si creano tabelle

I VALUES l'istruzione può essere utilizzata anche al posto della tabella di origine in CREATE TABLE … SELECT e CREATE VIEW … SELECT dichiarazioni.

Ecco un esempio:

CREATE TABLE t1 VALUES ROW(1,2,3), ROW(4,5,6);
SELECT * FROM t1;

Risultato:

+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |        2 |        3 |
|        4 |        5 |        6 |
+----------+----------+----------+

Possiamo anche fare questo:

CREATE TABLE t2 SELECT * FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS v;
SELECT * FROM t2;

Risultato:

+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |        2 |        3 |
|        4 |        5 |        6 |
+----------+----------+----------+

Quei due CREATE TABLE le dichiarazioni sono come fare questo:

CREATE TABLE t3 SELECT * FROM t2;
SELECT * FROM t3;

Risultato:

+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |        2 |        3 |
|        4 |        5 |        6 |
+----------+----------+----------+

In questo caso, ho usato il t2 table come tabella di origine, invece di fornire i valori in un VALUES dichiarazione.