¿Cómo seleccionar varias filas llenas de constantes?

176

Seleccionar constantes sin referirse a una tabla es perfectamente legal en una declaración SQL:

SELECT 1, 2, 3

El conjunto de resultados que devuelve este último es una sola fila que contiene los valores. Me preguntaba si hay una manera de seleccionar varias filas a la vez usando una expresión constante, algo así como:

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

Me gustaría algo como lo anterior que funcione y devuelva un conjunto de resultados con 3 filas y 3 columnas.

Blagovest Buyukliev
fuente
1
Su sintaxis imaginada arriba es más bonita (y más consistente con INSERT INTO) que la sintaxis oficial. Sólo digo.
Pete Alvin
2
@PeteAlvin La sintaxis imaginada ya tiene un significado en Postgres (se selecciona una sola fila con una tupla).
Kirill Bulygin
2
La siguiente respuesta del servidor sql funciona bien para el servidor sql y casi coincide con esta sintaxis. stackoverflow.com/a/53269562/2129481
BenPen

Respuestas:

203
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9
Rocío
fuente
2
Utilicé esto con SQL Server y funcionó, pero tuve que usar ASpara dar alias en el primerSELECT
Sled
gracias @ArtB, este comentario puede ayudar a otros desarrolladores a obtener la sintaxis correcta
Dewfy
3
También funciona perfectamente en Oracle APEX 5.1 para crear Classic Reporttablas con contenido estático, si se completa con FROM dualdespués de cada uno SELECT, valores y antes UNION ALLsi está presente.
VELFR
118

En PostgreSQL, puedes hacer:

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

En otros sistemas, solo use 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

En Oracle, SQL Servery PostgreSQL, también puede generar conjuntos de registros de un número arbitrario de filas (posible con una variable externa):

SELECT  level
FROM    dual
CONNECT BY
        level <= :n

en 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

en SQL Server,

SELECT  l
FROM    generate_series(1, $n) l

en PostgreSQL.

Quassnoi
fuente
1
+1 por responder la pregunta (ligeramente diferente) que tenía: cómo hacerlo SELECT 1en Oracle ( SELECT 1 FROM Dualfuncionó).
Aasmund Eldhuset
13

El siguiente VALUEScomando simple funciona para mí en PostgreSQL:

VALUES (1,2,3), (4,5,6), (7,8,9)
Tregoreg
fuente
1
También funciona en T-SQL como una cláusula de inserción de varias filas. Insertar en una tabla variable o temporal primero podría funcionar, pero múltiples pasos.
brianary
12

Pruebe la cláusula connect by en Oracle, algo como esto

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

Para obtener más información sobre la cláusula Connect by, siga este enlace: URL eliminada porque el sitio oraclebin ahora es malicioso.

Sushant Butta
fuente
8

Para Microsoft SQL Server o PostgreSQL, puede probar esta sintaxis

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

También puede ver un violín de SQL aquí: http://www.sqlfiddle.com/#!17/9eecb/34703/0

bigtunacan
fuente
1
Esto funciona absolutamente en SQL Server 2010. También múltiples columnas: SELECCIONE constantes, correo electrónico DESDE (VALORES (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (constantes, correo electrónico)
BenPen
7

Oráculo. Gracias a esta publicación PL / SQL: utilice la variable "Lista" en la cláusula Where in

Arme mi declaración de ejemplo para ingresar fácilmente valores manualmente (se reutilizan en la prueba de una aplicación por probadores):

WITH prods AS (
    SELECT column_value AS prods_code 
    FROM TABLE(
        sys.odcivarchar2list(
            'prod1', 
            'prod2'
        )
    )
)
SELECT * FROM prods
Petr Szturc
fuente
1
Esto fue un salvavidas. Una cosa a tener en cuenta: si se ha encontrado con un error de demasiados valores, puede hacer UNION ALL en la cláusula WITH.
ScrappyDev
5
SELECT * 
FROM DUAL 
CONNECT BY ROWNUM <= 9;
grokster
fuente
4

Así es como relleno datos estáticos en Oracle 10+ usando un truco XML ordenado.

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 fusión solo inserta las filas que faltan en la tabla original, lo cual es conveniente si desea volver a ejecutar su script de inserción.

Nicholas Sushkin
fuente
3

Una opción para 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
fuente
0

En oráculo

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

Aquí se explica cómo hacerlo utilizando las características 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
;
Stavr00
fuente
0

De esta manera puede ayudarte

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

Any_Table_In_Your_DataBase:cualquier tabla que contenga más de 3 registros, o use cualquier tabla del sistema. Aquí no tenemos ninguna preocupación con los datos de esa tabla.

Puede traer variaciones en el conjunto de resultados concatenando una columna con las columnas Primera, Segunda y Tercera de la Any_Table_In_Your_DataBasetabla.

Lali
fuente
Debe especificar qué base de datos usa. La palabra clave 'TOP' no funciona con Oracle.
Hans Deragon
0

En MySQL, puedes hacer: 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, también es posible dar los nombres de columna:

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
fuente
1
¿en qué versión de mysql estás para "valores (1,2), (3, 4);
Rene Wooller
¿Ese segundo ejemplo sigue seleccionando varias filas? Además, ninguno de ellos parece ser ejecutable como consultas en PhpMyAdmin. Desearía poder decirte en qué versión de MySQL estoy, pero las versiones de MySQL son muy confusas, y estoy seguro de que cuando lo resuelva, lo haré. estar fuera de tiempo para editar este comentario ...
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;

algo como eso

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
fuente