sql >> Databasteknik >  >> RDS >> Mysql

VALUES-uttalande i MySQL

I MySQL, VALUES sats returnerar en uppsättning av en eller flera rader som en tabell. I grund och botten är det en tabellvärdekonstruktor i enlighet med SQL-standarden, som också fungerar som en fristående SQL-sats.

VALUES uttalandet introducerades i MySQL 8.0.19.

Syntax

Den officiella syntaxen ser ut så här:

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

Exempel

Här är ett enkelt exempel för att visa hur det fungerar:

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

Resultat:

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

De resulterande kolumnerna heter implicit column_0 , column_1 , column_2 , och så vidare, som alltid börjar med 0 .

Vi kan se att varje ROW() radkonstruktorsatsen resulterar i en ny rad i den resulterande tabellen.

Varje ROW() innehåller en värdelista med ett eller flera skalära värden inom parentes. Ett värde kan vara en bokstavlig typ av MySQL-datatyp eller ett uttryck som löser sig till ett skalärt värde.

Därför kan vi också göra följande:

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

Resultat:

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

Eller sånt här:

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

Resultat:

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

ORDER BY Klausul

Syntaxen tillåter användning av ORDER BY klausul för att ordna resultaten. Jag har dock upptäckt att ORDER BY klausulen fungerar inte som förväntat på de system jag har försökt köra den mot.

Så här ska fungerar (enligt MySQL-dokumentationen):

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

Resultat:

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

Men på de två systemen som jag körde det uttalandet mot (MySQL 8.0.26 på Ubuntu 20.04.3 och MySQL 8.0.27 Homebrew på MacOS Monterery), ORDER BY klausulen fungerar inte alls. Kanske är detta en bugg.

LIMIT Klausul

Vi kan använda LIMIT sats för att begränsa antalet rader som matas ut:

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

Resultat:

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

Med en SELECT Uttalande

Vi kan också använda VALUES sats i en SELECT uttalande, som om VALUES Tabellkonstruktören var en faktisk tabell:

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;

Resultat:

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

ROW() Kan inte vara tom

En radkonstruktor kan inte vara tom om den inte används som källa i en INSERT påstående.

Så här händer om vi försöker använda en tom radkonstruktor:

VALUES ROW();

Resultat:

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() Kan innehålla nollvärden

Även om radkonstruktörer inte kan vara tomma, kan de innehålla Null-värden:

VALUES ROW(null, null);

Resultat:

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

Varje ROW() Måste innehålla samma antal värden

Varje ROW() i samma VALUES uttalandet måste ha samma antal värden i sin värdelista.

Därför kan vi inte göra detta:

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

Resultat:

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

Använda VALUES för att infoga data

Vi kan använda VALUES sats i kombination med INSERT och REPLACE satser för att infoga data i en tabell.

Exempel:

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

Det infogade två rader i en tabell som heter Pets . Detta förutsätter att tabellen redan finns.

Vi kan nu använda en SELECT uttalande för att se de nya värdena i tabellen:

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

Resultat:

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

Ovanstående INSERT uttalande motsvarar att göra följande:

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

När man skapar tabeller

VALUES satsen kan också användas i stället för källtabellen i CREATE TABLE … SELECT och CREATE VIEW … SELECT uttalanden.

Här är ett exempel:

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

Resultat:

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

Vi kan också göra detta:

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

Resultat:

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

Dessa två CREATE TABLE uttalanden är som att göra så här:

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

Resultat:

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

I det här fallet använde jag t2 tabellen som källtabell, istället för att tillhandahålla värdena i en VALUES uttalande.


  1. 2 sätt att skapa en tabell om den inte finns i SQL Server

  2. MySQL jämför DATE-sträng med sträng från DATETIME-fältet

  3. Hitta närmaste latitud/longitud med en SQL-fråga

  4. Hur man löser ORA-29285:filskrivfel