Comment sélectionner plusieurs lignes remplies de constantes?


176

Sélectionner des constantes sans faire référence à une table est parfaitement légal dans une instruction SQL:

SELECT 1, 2, 3

L'ensemble de résultats que ce dernier renvoie est une seule ligne contenant les valeurs. Je me demandais s'il existe un moyen de sélectionner plusieurs lignes à la fois en utilisant une expression constante, quelque chose comme:

SELECT ((1, 2, 3), (4, 5, 6), (7, 8, 9))

Je voudrais quelque chose comme celui ci-dessus qui fonctionne et renvoie un jeu de résultats avec 3 lignes et 3 colonnes.


1
Votre syntaxe imaginée ci-dessus est plus jolie (et plus cohérente avec INSERT INTO) que la syntaxe officielle. Dis simplement.
Pete Alvin

2
@PeteAlvin La syntaxe imaginée a déjà un sens dans Postgres (une seule ligne avec un tuple est sélectionnée).
Kirill Bulygin

2
La réponse du serveur sql ci-dessous fonctionne bien pour le serveur SQL et correspond presque à cette syntaxe. stackoverflow.com/a/53269562/2129481
BenPen

Réponses:


203
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9

2
J'ai utilisé cela avec SQL Server et cela a fonctionné, mais j'ai dû utiliser ASpour donner des alias le premierSELECT
Sled

merci @ArtB, ce commentaire peut aider d'autres développeurs à obtenir une syntaxe correcte
Dewfy

3
Fonctionne également parfaitement dans Oracle APEX 5.1 pour créer des Classic Reporttables avec un contenu statique, si elles sont complétées FROM dualaprès chacune SELECT, des valeurs et avant UNION ALLsi elles sont présentes.
VELFR

118

Dans PostgreSQL, vous pouvez faire:

SELECT  *
FROM    (
        VALUES
        (1, 2),
        (3, 4)
        ) AS q (col1, col2)

Dans d'autres systèmes, utilisez simplement UNION ALL:

SELECT  1 AS col1, 2 AS col2
-- FROM    dual
-- uncomment the line above if in Oracle
UNION ALL
SELECT  3 AS col1, 3 AS col2
-- FROM    dual
-- uncomment the line above if in Oracle

Dans Oracle, SQL Serveret PostgreSQL, vous pouvez également générer des jeux d'enregistrements d'un nombre arbitraire de lignes (pouvant être fournis avec une variable externe):

SELECT  level
FROM    dual
CONNECT BY
        level <= :n

dans Oracle,

WITH    q (l) AS
        (
        SELECT  1
        UNION ALL
        SELECT  l + 1
        FROM    q
        WHERE   l < @n
        )
SELECT  l
FROM    q
-- OPTION (MAXRECURSION 0)
-- uncomment line above if @n >= 100

dans SQL Server,

SELECT  l
FROM    generate_series(1, $n) l

dans PostgreSQL.


1
+1 pour avoir répondu à la question (légèrement différente) que j'avais: comment faire SELECT 1dans Oracle ( SELECT 1 FROM Dualtravaillé).
Aasmund Eldhuset

13

La VALUEScommande nue suivante fonctionne pour moi dans PostgreSQL:

VALUES (1,2,3), (4,5,6), (7,8,9)

1
Fonctionne également dans T-SQL comme une clause d'insertion sur plusieurs lignes. L'insertion dans une variable de table ou une table temporaire peut d'abord fonctionner, mais en plusieurs étapes.
brianary

12

Essayez la clause connect by dans oracle, quelque chose comme ça

select level,level+1,level+2 from dual connect by level <=3;

Pour plus d'informations sur la clause connect by, suivez ce lien: URL supprimée car le site oraclebin est désormais malveillant.


8

Pour Microsoft SQL Server ou PostgreSQL, vous pouvez essayer cette syntaxe

SELECT constants FROM (VALUES ('foo@gmail.com'), ('bar@gmail.com'), ('baz@gmail.com')) AS MyTable(constants)

Vous pouvez également afficher un SQL Fiddle ici: http://www.sqlfiddle.com/#!17/9eecb/34703/0


1
Cela fonctionne absolument dans SQL Server 2010. Plusieurs colonnes aussi: SELECT constantes, email FROM (VALUES (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (constantes, email)
BenPen

7

Oracle. Merci à cet article PL / SQL - Utiliser la variable "Liste" dans la clause Where In

J'ai rassemblé mon exemple de déclaration pour saisir facilement manuellement des valeurs (réutilisées lors du test d'une application par des testeurs):

WITH prods AS (
    SELECT column_value AS prods_code 
    FROM TABLE(
        sys.odcivarchar2list(
            'prod1', 
            'prod2'
        )
    )
)
SELECT * FROM prods

1
C'était une bouée de sauvetage. Une chose à noter: si vous avez rencontré une erreur de trop de valeurs, vous pouvez simplement faire UNION ALL dans la clause WITH.
ScrappyDev


4

Voici comment remplir des données statiques dans Oracle 10+ à l'aide d'une astuce XML soignée.

create table prop
(ID NUMBER,
 NAME varchar2(10),
 VAL varchar2(10),
 CREATED timestamp,
 CONSTRAINT PK_PROP PRIMARY KEY(ID)
);

merge into Prop p
using (
select 
  extractValue(value(r), '/R/ID') ID,
  extractValue(value(r), '/R/NAME') NAME,
  extractValue(value(r), '/R/VAL') VAL
from
(select xmltype('
<ROWSET>
   <R><ID>1</ID><NAME>key1</NAME><VAL>value1</VAL></R>
   <R><ID>2</ID><NAME>key2</NAME><VAL>value2</VAL></R>
   <R><ID>3</ID><NAME>key3</NAME><VAL>value3</VAL></R>
</ROWSET>
') xml from dual) input,
 table(xmlsequence(input.xml.extract('/ROWSET/R'))) r
) p_new
on (p.ID = p_new.ID)
when not matched then
insert
(ID, NAME, VAL, CREATED)
values
( p_new.ID, p_new.NAME, p_new.VAL, SYSTIMESTAMP );

La fusion insère uniquement les lignes manquantes dans la table d'origine, ce qui est pratique si vous souhaitez réexécuter votre script d'insertion.


3

Une option pour DB2:

SELECT 101 AS C1, 102 AS C2 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 201 AS C1, 202 AS C2 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 301 AS C1, 302 AS C2 FROM SYSIBM.SYSDUMMY1

0

Dans Oracle

SELECT
  CASE
    WHEN level = 1
    THEN 'HI'
    WHEN level = 2
    THEN 'BYE'
  END TEST
FROM dual
  CONNECT BY level <= 2;

0

Voici comment procéder à l'aide des fonctionnalités XML de DB2

SELECT *
FROM
XMLTABLE ('$doc/ROWSET/ROW' PASSING XMLPARSE ( DOCUMENT '
<ROWSET>
  <ROW>
    <A val="1" /> <B val="2" /> <C val="3" />
  </ROW>
  <ROW>
    <A val="4" /> <B val="5" /> <C val="6" />
  </ROW>
  <ROW>
    <A val="7" /> <B val="8" /> <C val="9" />
  </ROW>
</ROWSET>
') AS "doc"
   COLUMNS 
      "A" INT PATH 'A/@val',
      "B" INT PATH 'B/@val',
      "C" INT PATH 'C/@val'
) 
AS X
;

0

Cette façon peut vous aider

SELECT   TOP 3
         1 AS First, 
         2 AS Second, 
         3 AS Third 
FROM     Any_Table_In_Your_DataBase

Any_Table_In_Your_DataBase:n'importe quelle table contenant plus de 3 enregistrements, ou utilisez n'importe quelle table système. Ici, nous n'avons aucun souci avec les données de ce tableau.

Vous pouvez apporter des variations dans l'ensemble de résultats en concaténant une colonne avec les première, deuxième et troisième colonnes de la Any_Table_In_Your_DataBasetable.


Vous devez spécifier la base de données que vous utilisez. Le mot clé «TOP» ne fonctionne pas avec Oracle.
Hans Deragon

0

Dans MySQL, vous pouvez faire: values (1,2), (3, 4);

mysql> values (1,2), (3, 4);
+---+---+
| 1 | 2 |
+---+---+
| 1 | 2 |
| 3 | 4 |
+---+---+
2 rows in set (0.004 sec)

Avec MySQL 8, il est également possible de donner les noms des colonnes:

mysql> SELECT * FROM (SELECT 1, 2, 3, 4) AS dt (a, b, c, d);
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+

1
sur quelle version de mysql êtes-vous pour "values ​​(1,2), (3, 4);"?
Rene Wooller le

Ce deuxième exemple est-il encore en train de sélectionner plusieurs lignes? Ni l'un ni l'autre ne semblent être exécutables en tant que requêtes dans PhpMyAdmin. ne pas avoir le temps de modifier ce commentaire ...
still_dreaming_1

0
select (level - 1) * row_dif + 1 as a, (level - 1) * row_dif + 2 as b, (level - 1) * row_dif + 3 as c
    from dual 
    connect by level <= number_of_rows;

quelque chose comme ca

select (level - 1) * 3 + 1 as a, (level - 1) * 3 + 2 as b, (level - 1) * 3 + 3 as c
    from dual 
    connect by level <= 3;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.