sql >> Database >  >> RDS >> Mysql

WAARDEN Verklaring in MySQL

In MySQL zijn de VALUES instructie retourneert een set van een of meer rijen als een tabel. Kortom, het is een tabelwaardeconstructor in overeenstemming met de SQL-standaard, die ook functioneert als een op zichzelf staande SQL-instructie.

De VALUES statement is geïntroduceerd in MySQL 8.0.19.

Syntaxis

De officiële syntaxis gaat als volgt:

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

Voorbeeld

Hier is een eenvoudig voorbeeld om te demonstreren hoe het werkt:

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

Resultaat:

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

De resulterende kolommen hebben impliciet de naam column_0 , column_1 , column_2 , enzovoort, altijd beginnend met 0 .

We kunnen zien dat elke ROW() row constructor-clausule resulteert in een nieuwe rij in de resulterende tabel.

Elke ROW() bevat een waardenlijst van een of meer scalaire waarden tussen haakjes. Een waarde kan een letterlijke waarde zijn van elk MySQL-gegevenstype of een uitdrukking die wordt omgezet in een scalaire waarde.

Daarom kunnen we ook het volgende doen:

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

Resultaat:

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

Of dingen als dit:

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

Resultaat:

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

De ORDER BY Clausule

De syntaxis maakt het gebruik van de ORDER BY . mogelijk clausule om de resultaten te ordenen. Ik heb echter ontdekt dat de ORDER BY clausule werkt niet zoals verwacht op de systemen waar ik het tegen heb geprobeerd.

Hier is hoe het zou moeten werk (volgens de MySQL-documentatie):

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

Resultaat:

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

Maar op de twee systemen waar ik die verklaring tegen uitvoerde (MySQL 8.0.26 op Ubuntu 20.04.3 en MySQL 8.0.27 Homebrew op MacOS Monterery), de ORDER BY clausule werkt helemaal niet. Misschien is dit een bug.

De LIMIT Clausule

We kunnen de LIMIT . gebruiken clausule om het aantal rijen dat wordt uitgevoerd te beperken:

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

Resultaat:

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

Met een SELECT Verklaring

We kunnen ook de VALUES . gebruiken statement binnen een SELECT statement, alsof de VALUES table constructor waren een echte tabel:

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;

Resultaat:

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

ROW() Mag niet leeg zijn

Een rijconstructor kan niet leeg zijn, tenzij deze wordt gebruikt als bron in een INSERT uitspraak.

Dit is wat er gebeurt als we een lege rijconstructor proberen te gebruiken:

VALUES ROW();

Resultaat:

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 nulwaarden bevatten

Hoewel rijconstructors niet leeg kunnen zijn, kunnen ze null-waarden bevatten:

VALUES ROW(null, null);

Resultaat:

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

Elke ROW() Moet hetzelfde aantal waarden bevatten

Elke ROW() in dezelfde VALUES statement moet hetzelfde aantal waarden in de lijst met waarden hebben.

Daarom kunnen we dit niet doen:

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

Resultaat:

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

VALUES gebruiken om gegevens in te voegen

We kunnen de VALUES . gebruiken statement in combinatie met de INSERT en REPLACE instructies om gegevens in een tabel in te voegen.

Voorbeeld:

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

Dat voegde twee rijen toe aan een tabel met de naam Pets . Dit veronderstelt dat de tabel al bestaat.

We kunnen nu een SELECT . gebruiken statement om de nieuwe waarden in de tabel te zien:

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

Resultaat:

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

De bovenstaande INSERT statement is het equivalent van het volgende doen:

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

Bij het maken van tabellen

De VALUES statement kan ook worden gebruikt in plaats van de brontabel in CREATE TABLE … SELECT en CREATE VIEW … SELECT verklaringen.

Hier is een voorbeeld:

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

Resultaat:

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

We kunnen dit ook doen:

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

Resultaat:

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

Die twee CREATE TABLE uitspraken zijn als volgt:

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

Resultaat:

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

In dit geval gebruikte ik de t2 tabel als de brontabel, in plaats van de waarden op te geven in een VALUES verklaring.


  1. Hoe formatteer ik mijn orakel-query's zodat de kolommen niet overlopen?

  2. Wat zijn sequentiële versus parallelle streams in Java?

  3. Verschil tussen Inner join en Outer join in SQL

  4. Rails Resque-werknemers mislukken met PGError:server heeft de verbinding onverwacht gesloten