Esto funciona en los principales sistemas de gestión de bases de datos de relaciones con mayor probabilidad de aparecer en StackOverflow / dba.stackexchange, siendo SQL Server, MySQL, PostgreSQL y SQLite (WebSQL) .
select 'abc' abc, 1 def;
No funciona en Oracle. ¿Por qué necesitamos seleccionar DUAL en Oracle? ¿El estándar ISO / ANSI para SQL requiere una cláusula FROM para las instrucciones SELECT ?
Editar:
Según Bacon Bit
la respuesta, parece ser requerido por el estándar SQL.
Entonces, en realidad, porque el nombre DUAL es un nombre inapropiado, si tuviera que crear una tabla y nombrarla ATOM o ONE, por ejemplo create table one (atom int);
... select 'abc' abc, 1 def FROM one;
- ¿Hay una penalización de rendimiento en comparación con SELECT .. FROM DUAL
?
select
sin unfrom
. DB2 tiene una tabla ficticia similar llamada SYSIBM.SYSDUMMY1 . También es probable que ya lo sepas, pero cuando no se accede realmente aselect 'A' from dual
ladual
tabla , lo que responde a la pregunta en tu edición (que mereció una nueva pregunta por cierto).FROM
cláusula. Fuera de mi cabeza: Informix, Firebird y Apache Derby también lo requieren.values ('abc', 1)
. Por supuesto, puede también seleccionar de tal declaración:select abc from ( values ('abc',1) ) as t(abc,def)
Respuestas:
Estrictamente, sí, la
FROM
cláusula de unaSELECT
declaración no es opcional. La sintaxis para SQL-99 detalla elSELECT
enunciado básico , y laFROM
cláusula no tiene corchetes alrededor. Eso indica que el estándar lo considera no opcional:En el uso real, los programadores y los DBA a menudo encuentran útil hacer otras cosas además de manipular datos en tablas o manipular tablas y estructuras de datos. Este tipo de cosas está más allá del alcance del estándar SQL, que se ocupa más de las características de los datos que de los detalles básicos de las implementaciones específicas. Ya sea que queramos ejecutar
SELECT getdate()
oSELECT 1
oSELECT DB_NAME()
(o lo que prefiera su dialecto), en realidad no queremos datos de una tabla.Oracle elige resolver la discrepancia estándar y de implementación utilizando una tabla ficticia con la siguiente definición efectiva:
Otros RDBMS esencialmente suponen que se usa una tabla ficticia si no
FROM
se especifica ninguna .La historia de la tabla DUAL está en Wikipedia:
fuente
La ventaja
dual
es que el optimizador comprendedual
una tabla especial de una fila y una columna (convarchar2
el tipo de datos): cuando la usa en consultas, utiliza este conocimiento al desarrollar el plan.¿Por qué necesitamos seleccionar
dual
en Oracle?También puede seleccionar desde
dual
o desde sus propias tablas, puede hacerlo si lo desea.Para mí, me quedaré
dual
porque sé quedual
existe. Sé que tiene al menos 1 y como máximo 1 fila. Sé que el optimizador lo sabe tododual
y hace lo más eficiente para mí. El optimizador entiende quedual
es una tabla mágica y especial de 1 fila. Se detuvo en elselect *
porque debe haber una fila allí. Así es como funciona.fuente
DUAL
. ¡Ten cuidado!Las otras dos respuestas proporcionan buenos antecedentes para mi respuesta.
En las bases de datos Oracle, es tradicional y confiable. Fallará en otras bases de datos que no tienen una
DUAL
tabla. No es necesario que lo useDUAL
, pero le recomendaría que lo haga.Las bases de datos que cumplan con los estándares requerirán una
FROM
cláusula que especifique al menos una referencia de tabla. Si tiene una tabla ORDERS, el siguiente reemplazo para laFROM DUAL
cláusula funcionaría:Sustituya cualquier tabla o vista que pueda seleccionar y funcionará. Sustituya una tabla o vista de la que no pueda seleccionar y fallará.
DUAL
es más confiable ya que impide que un DBA lo rompa, todos los usuarios pueden seleccionarlo y obtendrán solo una fila en el conjunto de resultados. (Se rompe ocasionalmente).No conozco un verbo que cumpla con los estándares para acceder a datos que no están en una tabla sin incluir una referencia de tabla. Dado lo poco que accedo a esos datos, no veo tanta necesidad. Muchos de los casos con los que me encuentro pueden manejarse mejor de diferentes maneras.
fuente
SELECT CURRENT_TIMESTAMP FROM (VALUES(1)) V(C)
Es compatible con el estándar, creo, y no se basa en ninguna tabla en particular.