¿SELECCIONAR de la nada?

91

¿Es posible tener una declaración como

SELECT "Hello world"
WHERE 1 = 1

en SQL?

Lo principal que quiero saber es si puedo SELECCIONAR de la nada, es decir, no tener una cláusula FROM.

Ritwik Bose
fuente
3
Al mirar su comentario sobre @Rafael Belliard, es mejor que pregunte qué es lo que realmente quiere hacer. ¿Desea devolver alguna cadena si existen valores para una tabla determinada, por ejemplo?
Jim L
Sí, eso es exactamente lo que quería. Sé que puedo hacerlo, me preguntaba más si necesitaba un FROM NULLentre SELECTy WHERE. Fraseo oscuro principalmente porque es tarea y no quería que alguien viniera y me dijera la respuesta si mi instinto no estaba bien.
Ritwik Bose

Respuestas:

141

No es coherente entre los proveedores: Oracle, MySQL y DB2 admiten doble:

SELECT 'Hello world'
  FROM DUAL

... mientras que SQL Server, PostgreSQL y SQLite no requieren FROM DUAL:

SELECT 'Hello world'

MySQL es compatible en ambos sentidos.

Ponis dios mio
fuente
2
Siempre me lo he preguntado. ¿Por qué la elección del término dual para la tabla fantasma?
Alex Blakemore
5
@Alex: "La tabla DUAL original tenía dos filas (de ahí su nombre), pero posteriormente solo tenía una fila".
rebelde
7
En DB2 dual se llama 'sysibm.sysdummy1'
Danubian Sailor
1
En Postgresql, es posible crear una tabla ficticia llamada DUALy realizar consultas desde una tabla tipo fantasma.
Stephan
1
@AlexBlakemore "Creé la tabla DUAL como un objeto subyacente en el Diccionario de datos de Oracle. Nunca se pensó para que se viera, sino que se usó dentro de una vista que se esperaba que se consultara. La idea era que se pudiera hacer un JOIN para la tabla DUAL y cree dos filas en el resultado para cada fila de su tabla. Luego, usando GROUP BY, la combinación resultante podría resumirse para mostrar la cantidad de almacenamiento para la extensión de DATOS y para la extensión de ÍNDICE. El nombre, DUAL, parecía apto para el proceso de creación de un par de filas a partir de una sola "( en.wikipedia.org/wiki/DUAL_table )
Haga clic en Aceptar
15

Prueba esto.

Soltero:

SELECT *  FROM (VALUES ('Hello world')) t1 (col1) WHERE 1 = 1

Multi:

SELECT *  FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1

más detalles aquí: http://modern-sql.com/use-case/select-without-from

chuongtv
fuente
1
¡La única respuesta compatible con ANSI SQL! (A una pregunta sin dbms especificado.)
jarlh
¿Cuál es el propósito de WHERE 1 = 1? En PostgreSQL funciona sin él. ¿O se trata de otro DMBS?
Frankie Drake
Solo que SELECT * FROM (VALUES ("Hello world")) t1 (col1)todavía está bien. Wheresolo responde esta pregunta.
chuongtv
@chuongtv ¿Cómo se seleccionan varias filas?
Héctor
@Hector Simplemente siga la inserción de la estructura de SQL. asíSELECT * FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1
chuongtv
8

Aquí está la lista más completa de soporte de base de datos de dual de https://blog.jooq.org/tag/dual-table/ :

En muchos otros RDBMS, no hay necesidad de tablas ficticias, ya que puede emitir declaraciones como estas:

SELECT 1;
SELECT 1 + 1;
SELECT SQRT(2);

Estos son los RDBMS, donde lo anterior generalmente es posible:

  • H2
  • MySQL
  • Ingres
  • Postgres
  • SQLite
  • servidor SQL
  • Sybase ASE

En otros RDBMS, se requieren tablas ficticias, como en Oracle. Por lo tanto, deberá escribir cosas como estas:

SELECT 1       FROM DUAL;
SELECT 1 + 1   FROM DUAL;
SELECT SQRT(2) FROM DUAL;

Estos son los RDBMS y sus respectivas tablas ficticias:

  • DB2: SYSIBM.DUAL
  • Derby: SYSIBM.SYSDUMMY1
  • H2: opcionalmente compatible con DUAL
  • HSQLDB: INFORMATION_SCHEMA.SYSTEM_USERS
  • MySQL: opcionalmente compatible con DUAL
  • Oracle: DUAL
  • Sybase SQL en cualquier lugar: SYS.DUMMY

Ingres no tiene DUAL, pero en realidad lo necesitaría, ya que en Ingres no puede tener una cláusula WHERE, GROUP BY o HAVING sin una cláusula FROM.

Vadzim
fuente
6

En SQL Server, escriba:

Select 'Your Text'

No hay necesidad de la cláusula FROMo WHERE.

RollTide
fuente
5

Usted puede. Estoy usando las siguientes líneas en una consulta de StackExchange Data Explorer :

SELECT
(SELECT COUNT(*) FROM VotesOnPosts WHERE VoteTypeName = 'UpMod' AND UserId = @UserID AND PostTypeId = 2) AS TotalUpVotes,
(SELECT COUNT(*) FROM Answers WHERE UserId = @UserID) AS TotalAnswers

El intercambio de datos utiliza Transact-SQL (las extensiones propietarias de SQL Server para SQL).

Puede probarlo usted mismo ejecutando una consulta como:

SELECT 'Hello world'
palswim
fuente
El intercambio de datos es Azure, basado en SQL Server.
OMG Ponies
2

Creo que no es posible. Teóricamente: select realiza dos tipos de cosas:

  • estrechar / ampliar el conjunto (teoría de conjuntos);

  • mapeo del resultado.

El primero puede verse como una disminución horizontal opuesta a la cláusula where que puede verse como una disminución vertical. Por otro lado, una unión puede aumentar el conjunto horizontalmente donde una unión puede aumentar el conjunto verticalmente.

               augmentation          diminishing
horizontal     join/select              select   
vertical          union            where/inner-join

El segundo es un mapeo. Un mapeo, es más un conversor. En SQL, toma algunos campos y devuelve cero o más campos. En la selección, puede usar algunas funciones agregadas como suma, promedio, etc. O tomar todos los valores de las columnas y convertirlos en cadenas. En C # linq, decimos que una selección acepta un objeto de tipo T y devuelve un objeto de tipo U.

Creo que la confusión viene por el hecho de que usted puede hacer: select 'howdy' from <table_name>. Esta característica es el mapeo, el convertidor parte de la selección. ¡No está imprimiendo algo, sino convirtiendo! En tu ejemplo:

SELECT "
WHERE 1 = 1

está convirtiendo nada / nulo en "Hello world"y reduce el conjunto de nada / no tabla en una fila, lo que, en mi humilde opinión, no tiene ningún sentido.

Puede notar que, si no restringe el número de columnas, "Hello world"se imprime para cada fila disponible en la tabla. Espero que ya entiendas por qué. Su selecto quita nada a las columnas disponibles y crea una columna con el texto: "Hello world".

Entonces, mi respuesta es NO. No puede simplemente omitir la cláusula from porque la selección siempre necesita columnas de tabla para funcionar.

Andries
fuente
2

En SQL estándar, no. Una WHEREcláusula implica una expresión de tabla.

De la especificación SQL-92:

7.6 "cláusula where"

Función

Especifique una tabla derivada de la aplicación de una "condición de búsqueda" al resultado de la "cláusula from" anterior.

En turno:

7.4 "cláusula de"

Función

Especifique una tabla derivada de una o más tablas con nombre.

Una forma estándar de hacerlo (es decir, debería funcionar en cualquier producto SQL):

SELECT DISTINCT 'Hello world' AS new_value
  FROM AnyTableWithOneOrMoreRows
 WHERE 1 = 1;

... asumiendo que desea cambiar la WHEREcláusula a algo más significativo, de lo contrario, puede omitirse.

un día cuando
fuente
ERROR: la columna "hola mundo" no existe en my_table La consulta falló PostgreSQL dijo: la columna "hola mundo" no existe en my_table
Pål Brattberg
@ PålBrattberg: deberían ser comillas simples, ahora fijo.
cuando
¿Importa qué tabla se utiliza en términos de tiempo de procesamiento? ¿O el hecho de que SELECT no haga referencia a ninguna de las columnas hace que la tabla real sea irrelevante?
Allen Gould
@AllenGould: sería 'dependiente del proveedor' pero hay cortocircuitos obvios que podrían explotarse, por ejemplo, un caso es donde el optimizador reconoce que la SELECTcláusula comprende solo constantes y que AnyTableWithOneOrMoreRowses una tabla almacenada, por lo tanto, simplemente usa estadísticas para verificar si la tabla tiene cero filas.
cuando
2

Existe otra posibilidad, independiente VALUES():

VALUES ('Hello World');

Salida:

column1
Hello World

Es útil cuando necesita especificar varios valores de forma compacta:

VALUES (1, 'a'), (2, 'b'), (3, 'c');

Salida:

column1     column2
      1     a
      2     b
      3     c

Demostración de DBFiddle

Esta sintaxis es compatible con SQLite / PostgreSQL / DB LUW / MariaDB 10.3.

Lukasz Szozda
fuente
2

Para ClickHouse, la nada es system.one

SELECT 1 FROM system.one
simPod
fuente
1

En Firebird, puede hacer esto:

select "Hello world" from RDB$DATABASE;

RDB $ DATABASE es una tabla especial que siempre tiene una fila.

Robyn
fuente
0

Sé que esta es una pregunta antigua, pero la mejor solución para su pregunta es usar una subconsulta ficticia:

SELECT 'Hello World'
FROM (SELECT name='Nothing') n
WHERE 1=1

De esta manera, puede tener WHERE y cualquier cláusula (como Joins o Apply, etc.) después de la instrucción select, ya que la subconsulta ficticia fuerza el uso de la cláusula FROM sin cambiar el resultado.

DomingoR
fuente
1
Todavía tiene un SELECTsin un FROMen su subconsulta, por lo que aún fallará en Oracle, etc.
Pere
En Oracle es aún más simple porque puede simplemente SELECT 'Hello' FROM dual WHERE 1=1omitir la subconsulta.
DomingoR
El OP preguntó si era posible tener una declaración (es decir, a SELECT) sin una FROMcláusula. ¿No has leído la pregunta?
Pere
Leí la pregunta, pero a menos que no tenga experiencia en SQL (o no haya leído otras respuestas), sabe que no puede tener WHEREsin él FROM. Dado eso, respondí a la primera declaración de la pregunta del OP.
DomingoR
Bueno, tengo más de 15 años de experiencia en SQL, una Licenciatura en Computación y no recordaba si ahora tenía un WHERESQL estándar. También leo otras respuestas. Por cierto: lo correcto es que no se puede tener un SELECTsin unFROM , no un " WHEREsin un FROM" (?). ¿Dónde funciona tu consulta, @DomingoR? Todavía tiene un SELECTsin un FROM(en la subconsulta), fallando así en aquellos DBMS que no permiten tener consultas sin un FROMy trabajando solo en aquellos que se desvían del SQL estándar y permiten no tener un FROMen el SELECT. Entonces tu respuesta no sirve para nada.
Pere
0

Estoy usando firebird En primer lugar, cree una tabla de una columna llamada "NoTable" como esta

CREATE TABLE NOTABLE 
(
  NOCOLUMN              INTEGER
);
INSERT INTO NOTABLE VALUES (0); -- You can put any value

ahora puedes escribir esto

select 'hello world' as name

de notable

puede agregar cualquier columna que desee que se muestre

Yous Athmane
fuente
0

Para DB2:

`VALUES('Hello world')`

También puede hacer varias "filas":

`VALUES('Hello world'),('Goodbye world');`

Incluso puede usarlos en combinaciones siempre que los tipos coincidan:

VALUES(1,'Hello world')
UNION ALL
VALUES(2,'Goodbye world');
Brad Mace
fuente