Cela fonctionne dans les principaux systèmes de gestion de bases de données de relations les plus susceptibles d'apparaître sur StackOverflow / dba.stackexchange, à savoir SQL Server, MySQL, PostgreSQL et SQLite (WebSQL) .
select 'abc' abc, 1 def;
Cela ne fonctionne pas sur Oracle. Pourquoi devons-nous choisir parmi DUAL dans Oracle? La norme ISO / ANSI pour SQL requiert-elle une clause FROM pour les instructions SELECT ?
Éditer:
Par Bacon Bit
réponse, il semble requis par la norme SQL.
Donc en réalité, parce que le nom DUAL est si mal approprié, si je devais créer une table et la nommer ATOM ou ONE, par exemple create table one (atom int);
.. select 'abc' abc, 1 def FROM one;
- Y a-t-il une pénalité de performance par rapport à SELECT .. FROM DUAL
?
select
sansfrom
. DB2 possède une table factice similaire appelée SYSIBM.SYSDUMMY1 . De plus, vous le savez probablement déjà, mais quand vousselect 'A' from dual
, ledual
tableau n'est pas vraiment accessible , ce qui répond à la question dans votre édition (qui méritait une nouvelle question btw).FROM
clause. Du haut de ma tête: Informix, Firebird et Apache Derby en ont également besoin.values ('abc', 1)
. Vous pouvez bien sûr également sélectionner une telle déclaration:select abc from ( values ('abc',1) ) as t(abc,def)
Réponses:
Strictement, oui, la
FROM
clause d'uneSELECT
déclaration n'est pas facultative. La syntaxe de SQL-99 détaille laSELECT
déclaration de base et laFROM
clause n'a pas de crochets autour. Cela indique que la norme considère qu'elle n'est pas facultative:En utilisation réelle, les programmeurs et les administrateurs de base de données trouvent souvent utile de faire autre chose que de manipuler des données dans des tableaux ou de manipuler des tableaux et des structures de données. Ce type de chose dépasse largement le cadre de la norme SQL, qui s'intéresse davantage aux fonctionnalités de données qu'aux écrous et boulons d'implémentations spécifiques. Que nous voulions exécuter
SELECT getdate()
ouSELECT 1
ouSELECT DB_NAME()
(ou ce que votre dialecte préfère), nous ne voulons pas réellement de données d'une table.Oracle choisit de résoudre l'écart standard et d'implémentation à l'aide d'un tableau factice avec la définition efficace suivante:
D'autres SGBDR supposent essentiellement qu'une table fictive est utilisée si aucun
FROM
n'est spécifié.L' histoire de la table DUAL est sur Wikipédia:
la source
L'avantage
dual
est que l'optimiseur comprenddual
une table spéciale à une ligne et une colonne (avecvarchar2
type de données) - lorsque vous l'utilisez dans des requêtes, il utilise ces connaissances lors du développement du plan.Pourquoi devons-nous sélectionner
dual
dans Oracle?Vous pouvez également sélectionner à partir de
dual
ou à partir de vos propres tables, si vous le souhaitez.Pour moi, je vais m'en tenir
dual
parce que je sais qu'ildual
existe. Je sais qu'il a au moins 1 et au plus 1 ligne. Je sais que l'optimiseur sait toutdual
et fait la chose la plus efficace pour moi. L'optimiseur comprend qu'ildual
s'agit d'un tableau magique spécial à 1 ligne. Il s'est arrêté leselect *
parce qu'il doit y avoir une rangée là-dedans. C'est donc comme ça que ça fonctionne.la source
DUAL
. Faites attention!Les deux autres réponses fournissent un bon contexte pour ma réponse.
Sur les bases de données Oracle, il est traditionnel et fiable. Il échouera sur d'autres bases de données qui n'ont pas de
DUAL
table. Il n'est pas nécessaire que vous l'utilisiezDUAL
, mais je vous le recommande.Les bases de données conformes aux normes nécessiteront une
FROM
clause spécifiant au moins la référence de la table. Si vous avez une table ORDERS, le remplacement suivant de laFROM DUAL
clause fonctionnerait:Remplacez n'importe quelle table ou vue que vous pouvez sélectionner et cela fonctionnera. Remplacez une table ou une vue que vous ne pouvez pas sélectionner et elle échouera.
DUAL
est plus fiable que si un DBA le brise, tous les utilisateurs peuvent le sélectionner et n'obtiendront qu'une seule ligne dans le jeu de résultats. (Il se casse parfois.)Je ne connais pas de verbe conforme aux normes pour accéder aux données qui ne sont pas dans un tableau sans inclure une référence de tableau. Étant donné le peu d'accès à ces données, je ne vois pas un tel besoin. Bon nombre des cas que je rencontre peuvent être mieux traités de différentes manières.
la source
SELECT CURRENT_TIMESTAMP FROM (VALUES(1)) V(C)
est conforme aux normes, je crois, et ne repose sur aucune table particulière.