Como selecionar várias linhas preenchidas com constantes?

176

Selecionar constantes sem se referir a uma tabela é perfeitamente legal em uma instrução SQL:

SELECT 1, 2, 3

O conjunto de resultados que o último retorna é uma única linha que contém os valores. Eu queria saber se existe uma maneira de selecionar várias linhas ao mesmo tempo usando uma expressão constante, algo como:

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

Eu gostaria de algo como o acima, que funciona e retorna um conjunto de resultados com 3 linhas e 3 colunas.

Blagovest Buyukliev
fonte
1
Sua sintaxe imaginada acima é mais bonita (e mais consistente com INSERT INTO) do que a sintaxe oficial. Apenas dizendo.
Pete Alvin
2
@PeteAlvin A sintaxe imaginada já tem um significado no Postgres (uma única linha com uma tupla é selecionada).
Kirill Bulygin
2
A resposta do servidor sql abaixo funciona bem para o servidor sql e quase corresponde a esta sintaxe. stackoverflow.com/a/53269562/2129481
BenPen

Respostas:

203
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9
Dewfy
fonte
2
Eu usei isso com o SQL Server e funcionou, mas tive que usar ASpara dar aliases no primeiroSELECT
Sled
obrigado @ArtB, este comentário pode ajudar outros desenvolvedores para obter a sintaxe correta
Dewfy
3
Também funciona perfeitamente no Oracle APEX 5.1 para criar Classic Reporttabelas com conteúdo estático, se concluídas com valores FROM dualdepois de cada um SELECTe antes UNION ALLse presentes.
VELFR
118

Em PostgreSQL, você pode fazer:

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

Em outros sistemas, basta usar 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

Em Oracle, SQL Servere PostgreSQL, você também pode gerar conjuntos de registros com número arbitrário de linhas (disponibilizável com uma variável externa):

SELECT  level
FROM    dual
CONNECT BY
        level <= :n

em 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

em SQL Server,

SELECT  l
FROM    generate_series(1, $n) l

no PostgreSQL.

Quassnoi
fonte
1
+1 por responder à pergunta (um pouco diferente) que eu tinha: como fazer SELECT 1no Oracle ( SELECT 1 FROM Dualfuncionou).
Aasmund Eldhuset
13

O seguinte VALUEScomando bare funciona para mim no PostgreSQL:

VALUES (1,2,3), (4,5,6), (7,8,9)
Tregoreg
fonte
1
Também funciona no T-SQL como uma cláusula de inserção de várias linhas. Inserir em uma variável de tabela ou tabela temporária primeiro poderia funcionar, mas várias etapas.
21916 brianary
12

Experimente a cláusula connect by no oracle, algo como isto

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

Para obter mais informações sobre a cláusula connect by, siga este link: URL removido porque o site oraclebin agora é malicioso.

Sushant Butta
fonte
8

Para Microsoft SQL Server ou PostgreSQL, convém tentar esta sintaxe

SELECT constants FROM (VALUES ('[email protected]'), ('[email protected]'), ('[email protected]')) AS MyTable(constants)

Você também pode visualizar um SQL Fiddle aqui: http://www.sqlfiddle.com/#!17/9eecb/34703/0

bigtunacan
fonte
1
Isso funciona absolutamente no SQL Server 2010. Várias colunas também: SELECT constantes, email FROM (VALUES (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (constantes, email)
BenPen
7

Oráculo. Graças a este post PL / SQL - Use a variável "List" na cláusula Where In

Eu montei minha instrução de exemplo para inserir valores manualmente com facilidade (sendo reutilizados no teste de um aplicativo pelos testadores):

WITH prods AS (
    SELECT column_value AS prods_code 
    FROM TABLE(
        sys.odcivarchar2list(
            'prod1', 
            'prod2'
        )
    )
)
SELECT * FROM prods
Petr Szturc
fonte
1
Este foi um salva-vidas. Uma coisa a ser observada: se você tiver encontrado um erro de muitos valores, poderá executar um UNION ALL na cláusula WITH.
ScrappyDev 18/09/19
5
SELECT * 
FROM DUAL 
CONNECT BY ROWNUM <= 9;
grokster
fonte
4

Aqui está como eu preencho dados estáticos no Oracle 10+ usando um truque XML puro.

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

A mesclagem insere apenas as linhas que estão faltando na tabela original, o que é conveniente se você deseja executar novamente o script de inserção.

Nicholas Sushkin
fonte
3

Uma opção para o 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
Vitaliy Ulantikov
fonte
0

No Oracle

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

Aqui está como fazer isso usando os recursos XML do 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
;
Stavr00
fonte
0

Desta forma, pode ajudá-lo

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

Any_Table_In_Your_DataBase:qualquer tabela que contenha mais de 3 registros ou use qualquer tabela do sistema. Aqui não temos preocupação com os dados dessa tabela.

Você pode trazer variações no conjunto de resultados concatenando uma coluna com as colunas Primeira, Segunda e Terceira da Any_Table_In_Your_DataBasetabela.

Lali
fonte
Você deve especificar qual banco de dados você usa. A palavra-chave 'TOP' não funciona com o Oracle.
Hans Deragon
0

No MySQL, você pode fazer: values (1,2), (3, 4);

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

Com o MySQL 8, também é possível fornecer os nomes das colunas:

mysql> SELECT * FROM (SELECT 1, 2, 3, 4) AS dt (a, b, c, d);
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
Benedikt Köppel
fonte
1
em qual versão do mysql você está "valores (1,2), (3, 4);"?
Rene Wooller
Esse segundo exemplo ainda está selecionando várias linhas? Além disso, nenhum deles parece ser executável como consultas no PhpMyAdmin. Gostaria de poder dizer em qual versão do MySQL estou, mas as versões do MySQL são muito confusas e tenho certeza que, quando descobrir, vou tempo para editar este comentário ...
still_dreaming_1 28/04
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;

algo parecido

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;
Dejoto
fonte