Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Instrução VALUES no MySQL


No MySQL, os VALUES A instrução retorna um conjunto de uma ou mais linhas como uma tabela. Basicamente, é um construtor de valor de tabela de acordo com o padrão SQL, que também funciona como uma instrução SQL autônoma.

Os VALUES foi introduzida no MySQL 8.0.19.

Sintaxe


A sintaxe oficial é assim:
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

Exemplo


Aqui está um exemplo simples para demonstrar como funciona:
VALUES ROW(1, 2, 3), ROW(4, 5, 6);

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

As colunas resultantes são chamadas implicitamente de column_0 , column_1 , column_2 , e assim por diante, sempre começando com 0 .

Podemos ver que cada ROW() A cláusula construtora de linha resulta em uma nova linha na tabela resultante.

Cada ROW() contém uma lista de valores de um ou mais valores escalares entre parênteses. Um valor pode ser um literal de qualquer tipo de dados MySQL ou uma expressão que resolva para um valor escalar.

Portanto, também podemos fazer o seguinte:
VALUES ROW("Black", "Cat"), ROW("Yellow", "Dog");

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

Ou coisas assim:
VALUES 
   ROW(CURDATE(), DATE_ADD(CURDATE(), INTERVAL 10 YEAR)),
   ROW(CURTIME(), DATE_ADD(CURTIME(), INTERVAL 2 HOUR));

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

O ORDER BY Cláusula


A sintaxe permite o uso do ORDER BY cláusula para ordenar os resultados. No entanto, descobri que o ORDER BY cláusula não funciona como esperado nos sistemas em que tentei executá-la.

Veja como deveria trabalho (de acordo com a documentação do MySQL):
VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8) ORDER BY column_1;

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

Mas nos dois sistemas em que executei essa instrução (MySQL 8.0.26 no Ubuntu 20.04.3 e MySQL 8.0.27 Homebrew no MacOS Monterery), o ORDER BY cláusula não funciona. Talvez isso seja um bug.

O LIMIT Cláusula


Podemos usar o LIMIT cláusula para limitar o número de linhas que são geradas:
VALUES 
   ROW('Black', 'Cat'), 
   ROW('Yellow', 'Dog'), 
   ROW('Aqua', 'Fish')
LIMIT 2;

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

Com um SELECT Declaração


Também podemos usar os VALUES declaração dentro de um SELECT instrução, como se os VALUES construtor de tabela eram uma tabela real:
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;

Resultado:
+---------+---------+
| PetName | PetType |
+---------+---------+
| Bark    | Dog     |
+---------+---------+

ROW() Não pode estar vazio


Um construtor de linha não pode estar vazio, a menos que esteja sendo usado como fonte em um INSERT demonstração.

Aqui está o que acontece se tentarmos usar um construtor de linha vazio:
VALUES ROW();

Resultado:
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() Pode conter valores nulos


Embora os construtores de linha não possam estar vazios, eles podem conter valores nulos:
VALUES ROW(null, null);

Resultado:
+----------+----------+
| column_0 | column_1 |
+----------+----------+
|     NULL |     NULL |
+----------+----------+

Cada ROW() Deve conter o mesmo número de valores


Cada ROW() no mesmo VALUES A instrução deve ter o mesmo número de valores em sua lista de valores.

Portanto, não podemos fazer isso:
VALUES ROW(1, 2), ROW(3);

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

Usando VALUES para inserir dados


Podemos usar os VALUES instrução em conjunto com o INSERT e REPLACE instruções para inserir dados em uma tabela.

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

Isso inseriu duas linhas em uma tabela chamada Pets . Isso pressupõe que a tabela já existe.

Agora podemos usar um SELECT instrução para ver os novos valores na tabela:
SELECT * FROM Pets
WHERE PetId IN (9, 10);

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

O INSERT acima declaração é o equivalente a fazer o seguinte:
INSERT INTO Pets VALUES 
   (9, 3, 1, 'Woof', '2020-10-03'), 
   (10, 4, 5, 'Ears', '2022-01-11');

Ao criar tabelas


Os VALUES também pode ser usada no lugar da tabela de origem em CREATE TABLE … SELECT e CREATE VIEW … SELECT declarações.

Aqui está um exemplo:
CREATE TABLE t1 VALUES ROW(1,2,3), ROW(4,5,6);
SELECT * FROM t1;

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

Também podemos fazer isso:
CREATE TABLE t2 SELECT * FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS v;
SELECT * FROM t2;

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

Esses dois CREATE TABLE declarações são como fazer isso:
CREATE TABLE t3 SELECT * FROM t2;
SELECT * FROM t3;

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

Neste caso, usei o t2 table como a tabela de origem, em vez de fornecer os valores em um VALUES demonstração.