Come selezionare più righe piene di costanti?


176

La selezione di costanti senza fare riferimento a una tabella è perfettamente legale in un'istruzione SQL:

SELECT 1, 2, 3

Il set di risultati che quest'ultimo restituisce è una singola riga contenente i valori. Mi chiedevo se c'è un modo per selezionare più righe contemporaneamente usando un'espressione costante, qualcosa del tipo:

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

Vorrei qualcosa di simile a quanto sopra che funziona e restituisce un set di risultati con 3 righe e 3 colonne.


1
La tua sintassi immaginata sopra è più bella (e più coerente con INSERT INTO) rispetto alla sintassi ufficiale. Dillo e basta.
Pete Alvin,

2
@PeteAlvin La sintassi immaginata ha già un significato in Postgres (è selezionata una singola riga con una tupla).
Kirill Bulygin,

2
La risposta del server sql di seguito funziona bene per il server sql e corrisponde quasi a questa sintassi. stackoverflow.com/a/53269562/2129481
BenPen

Risposte:


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

2
Ho usato questo con SQL Server e ha funzionato, ma ho dovuto usare ASper dare gli alias sul primoSELECT
Sled

grazie @ArtB, questo commento può aiutare altri sviluppatori a ottenere la sintassi corretta
Dewfy,

3
Funziona perfettamente anche in Oracle APEX 5.1 per creare Classic Reporttabelle con contenuto statico, se completato con valori FROM dualdopo ciascuno SELECT, e prima UNION ALLse presente.
VELFR,

118

In PostgreSQL, puoi fare:

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

In altri sistemi, basta usare 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

In Oracle, SQL Servere PostgreSQL, puoi anche generare recordset di un numero arbitrario di righe (fornito con una variabile esterna):

SELECT  level
FROM    dual
CONNECT BY
        level <= :n

in 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

in SQL Server,

SELECT  l
FROM    generate_series(1, $n) l

in PostgreSQL.


1
+1 per aver risposto alla domanda (leggermente diversa) che avevo: come fare SELECT 1in Oracle ( SELECT 1 FROM Dualfunzionava).
Aasmund Eldhuset,

13

Il seguente VALUEScomando bare funziona per me in PostgreSQL:

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

1
Funziona anche in T-SQL come una clausola insert a più righe. L'inserimento in una variabile di tabella o una tabella temporanea può funzionare prima, ma più passaggi.
brianary,

12

Prova la clausola connect by in oracle, qualcosa del genere

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

Per ulteriori informazioni sulla clausola connect by segui questo link: URL rimosso perché il sito oraclebin è ora dannoso.


8

Per Microsoft SQL Server o PostgreSQL potresti provare questa sintassi

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

Puoi anche visualizzare un violino SQL qui: http://www.sqlfiddle.com/#!17/9eecb/34703/0


1
Funziona assolutamente in SQL Server 2010. Anche colonne multiple: SELEZIONA costanti, email DA (VALORI (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (costanti, e-mail)
BenPen

7

Oracolo. Grazie a questo post PL / SQL - Utilizzare la variabile "Elenco" nella clausola Where In

Ho messo insieme la mia dichiarazione di esempio per inserire facilmente i valori manualmente (riutilizzati nel test di un'applicazione da parte dei tester):

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

1
Questo è stato un salvavita. Una cosa da notare: se hai riscontrato un errore di troppi valori, puoi semplicemente eseguire UNION ALL nella clausola WITH.
ScrappyDev,


4

Ecco come popolare i dati statici in Oracle 10+ usando un trucco XML pulito.

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 );

L'unione inserisce solo le righe mancanti nella tabella originale, il che è utile se si desidera rieseguire lo script di inserimento.


3

Un'opzione per 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

In Oracle

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

0

Ecco come farlo utilizzando le funzionalità XML di 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

In questo modo può aiutarti

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

Any_Table_In_Your_DataBase:qualsiasi tabella che contiene più di 3 record o utilizzare qualsiasi tabella di sistema. Qui non ci occupiamo dei dati di quella tabella.

È possibile apportare variazioni nel set di risultati concatenando una colonna con la prima, la seconda e la terza colonna della Any_Table_In_Your_DataBasetabella.


È necessario specificare quale database si utilizza. La parola chiave "TOP" non funziona con Oracle.
Hans Deragon,

0

In MySQL puoi fare: values (1,2), (3, 4);

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

Con MySQL 8, è anche possibile assegnare i nomi delle colonne:

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

1
quale versione di mysql stai usando per "valori (1,2), (3, 4);"?
Rene Wooller,

Quel secondo esempio sta ancora selezionando più righe? Inoltre nessuno dei due sembra essere eseguibile come query in PhpMyAdmin .. Vorrei poterti dire su quale versione di MySQL sono su, ma le versioni di MySQL sono così confuse, e sono sicuro che quando lo capirò, lo farò non avere tempo per modificare questo commento ...
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;

qualcosa del genere

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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.