SELECT à partir de rien?

90

Est-il possible d'avoir une déclaration comme

SELECT "Hello world"
WHERE 1 = 1

en SQL?

La principale chose que je veux savoir, c'est que je peux SELECT à partir de rien, c'est-à-dire ne pas avoir de clause FROM.

Ritwik Bose
la source
3
En regardant votre commentaire sur @Rafael Belliard, vous feriez peut-être mieux de demander ce que vous voulez réellement faire. Voulez-vous retourner une chaîne si des valeurs existent pour une table donnée par exemple?
Jim L
Oui, c'est exactement ce que je voulais. Je sais que je peux le faire, je me demandais plus si j'avais besoin d'un FROM NULLentre SELECTet WHERE. Formulation obscure principalement parce que ce sont des devoirs et que je ne voulais pas que quelqu'un vienne me dire la réponse si mon instinct était faux.
Ritwik Bose

Réponses:

140

Ce n'est pas cohérent entre les fournisseurs - Oracle, MySQL et DB2 prennent en charge le double:

SELECT 'Hello world'
  FROM DUAL

... alors que SQL Server, PostgreSQL et SQLite ne nécessitent pas FROM DUAL:

SELECT 'Hello world'

MySQL prend en charge les deux méthodes.

Poneys OMG
la source
2
Je me suis toujours demandé. Pourquoi le choix du terme dual pour la table fantôme?
Alex Blakemore
5
@Alex: "La table DUAL d'origine contenait deux lignes (d'où son nom), mais par la suite, elle ne contenait qu'une seule ligne."
rebelliard
7
Sur DB2, le dual s'appelle 'sysibm.sysdummy1'
Danubian Sailor
1
Sur Postgresql, il est possible de créer une table factice appelée DUALet d'effectuer des requêtes à partir d'une table de type fantôme.
Stephan
1
@AlexBlakemore "J'ai créé la table DUAL en tant qu'objet sous-jacent dans le dictionnaire de données Oracle. Elle n'a jamais été conçue pour être vue elle-même, mais utilisée à la place dans une vue qui devait être interrogée. L'idée était que vous pourriez faire un JOIN pour la table DUAL et créez deux lignes dans le résultat pour chaque ligne de votre table. Ensuite, en utilisant GROUP BY, la jointure résultante pourrait être récapitulée pour afficher la quantité de stockage pour l'étendue DATA et pour l'étendue INDEX. Le nom, DUAL, semblait approprié pour le processus de création d'une paire de lignes à partir d'une seule "( en.wikipedia.org/wiki/DUAL_table )
Cliquez sur Ok le
28

Dans Oracle :

SELECT 'Hello world' FROM dual

Double équivalent dans SQL Server :

SELECT 'Hello world' 
rebelliard
la source
1
Puis-je mettre une déclaration comme WHERE (SELECT ... )après?
Ritwik Bose
14

Essaye ça.

Célibataire:

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

plus de détails ici: http://modern-sql.com/use-case/select-without-from

chuongtv
la source
1
La seule réponse conforme ANSI SQL! (À une question sans dbms spécifié.)
jarlh
Quel est le but de WHERE 1 = 1? Sur PostgreSQL fonctionne sans cela. Ou cela concerne-t-il un autre DMBS?
Frankie Drake
Seulement SELECT * FROM (VALUES ("Hello world")) t1 (col1)encore bien. Whererépondez simplement à cette question.
chuongtv
@chuongtv Comment sélectionnez-vous plusieurs lignes?
Hector
@Hector Suivez simplement l'insertion struct de SQL. comme çaSELECT * FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1
chuongtv
8

Voici la liste la plus complète du support de base de données de dual à partir de https://blog.jooq.org/tag/dual-table/ :

Dans de nombreux autres SGBDR, il n'y a pas besoin de tables factices, car vous pouvez émettre des instructions comme celles-ci:

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

Voici le SGBDR, où ce qui précède est généralement possible:

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

Dans d'autres SGBDR, des tables factices sont requises, comme dans Oracle. Par conséquent, vous devrez écrire des choses comme celles-ci:

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

Voici le SGBDR et leurs tables factices respectives:

  • DB2: SYSIBM.DUAL
  • Derby: SYSIBM.SYSDUMMY1
  • H2: prend en charge en option DUAL
  • HSQLDB: INFORMATION_SCHEMA.SYSTEM_USERS
  • MySQL: prend en charge DUAL en option
  • Oracle: DUAL
  • Sybase SQL Anywhere: SYS.DUMMY

Ingres n'a pas de DUAL, mais en aurait réellement besoin car dans Ingres vous ne pouvez pas avoir de clause WHERE, GROUP BY ou HAVING sans clause FROM.

Vadzim
la source
6

Dans le type SQL Server:

Select 'Your Text'

Il n'y a pas besoin de la clause FROMou WHERE.

RollTide
la source
5

Vous pouvez. J'utilise les lignes suivantes dans une requête 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

L'échange de données utilise Transact-SQL (les extensions propriétaires SQL Server de SQL).

Vous pouvez l'essayer vous-même en exécutant une requête comme:

SELECT 'Hello world'
palswim
la source
L'échange de données est Azure, basé sur SQL Server.
OMG Ponies
2

Je pense que ce n’est pas possible. Théoriquement: select effectue deux sortes de choses:

  • rétrécir / élargir l'ensemble (théorie des ensembles);

  • cartographie du résultat.

La première peut être vue comme une diminution horizontale opposée à la clause where qui peut être vue comme une diminution verticale. D'un autre côté, une jointure peut augmenter l'ensemble horizontalement alors qu'une union peut augmenter l'ensemble verticalement.

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

Le second est une cartographie. Une cartographie, c'est plus un convertisseur. En SQL, il prend certains champs et renvoie zéro ou plusieurs champs. Dans la sélection, vous pouvez utiliser certaines fonctions d'agrégation comme, sum, avg etc. Ou prendre toutes les valeurs de colonne et les convertir en chaîne. En C # linq, on dit qu'un select accepte un objet de type T et renvoie un objet de type U.

Je pense que la confusion vient du fait que vous pouvez faire: select 'howdy' from <table_name>. Cette fonctionnalité est le mappage, la partie convertisseur de la sélection. Vous n'imprimez pas quelque chose, mais vous convertissez! Dans votre exemple:

SELECT "
WHERE 1 = 1

vous convertissez rien / null en "Hello world"et vous réduisez l'ensemble de rien / pas de table en une seule ligne, ce qui, à mon avis, n'a aucun sens.

Vous remarquerez peut-être que, si vous ne contraignez pas le nombre de colonnes, "Hello world"est imprimé pour chaque ligne disponible dans le tableau. J'espère, vous comprenez pourquoi maintenant. Votre sélection ne prend rien aux colonnes et crée une colonne avec le texte disponible: "Hello world".

Donc, ma réponse est NON. Vous ne pouvez pas simplement omettre la clause from car la sélection a toujours besoin de colonnes de table pour fonctionner.

Andries
la source
2

En SQL standard, non. Une WHEREclause implique une expression de table.

À partir de la spécification SQL-92:

7.6 "clause where"

Fonction

Spécifiez une table dérivée de l'application d'une "condition de recherche" au résultat de la "clause from" précédente.

À son tour:

7.4 "de la clause"

Fonction

Spécifiez une table dérivée d'une ou de plusieurs tables nommées.

Une manière standard de le faire (c'est-à-dire qui devrait fonctionner sur n'importe quel produit SQL):

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

... en supposant que vous vouliez changer la WHEREclause en quelque chose de plus significatif, sinon elle peut être omise.

un jour quand
la source
ERREUR: la colonne "bonjour le monde" n'existe pas dans ma_table La requête a échoué PostgreSQL a dit: la colonne "bonjour le monde" n'existe pas dans ma_table
Pål Brattberg
@ PålBrattberg: devrait être des guillemets simples, maintenant corrigés.
jour
La table utilisée est-elle importante en termes de temps de traitement? Ou est-ce que le fait que SELECT ne référence aucune des colonnes rend la table réelle non pertinente?
Allen Gould
@AllenGould: cela dépendrait du fournisseur mais il y a des courts-circuits évidents qui pourraient être exploités, par exemple, un cas est où l'optimiseur reconnaît que la SELECTclause comprend uniquement des constantes et c'est AnyTableWithOneOrMoreRowsune table stockée, donc utilise simplement des statistiques pour vérifier si la table a zéro ligne.
jour du
2

Il existe une autre possibilité - autonome VALUES():

VALUES ('Hello World');

Production:

column1
Hello World

C'est utile lorsque vous devez spécifier plusieurs valeurs de manière compacte:

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

Production:

column1     column2
      1     a
      2     b
      3     c

Démo DBFiddle

Cette syntaxe est prise en charge par SQLite / PostgreSQL / DB LUW / MariaDB 10.3.

Lukasz Szozda
la source
2

Pour ClickHouse, le rien n'est system.one

SELECT 1 FROM system.one
simPod
la source
1

Dans Firebird, vous pouvez faire ceci:

select "Hello world" from RDB$DATABASE;

RDB $ DATABASE est une table spéciale qui a toujours une ligne.

Robyn
la source
0

Je sais que c'est une vieille question, mais la meilleure solution de contournement pour votre question consiste à utiliser une sous-requête factice:

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

De cette façon, vous pouvez avoir WHERE et n'importe quelle clause (comme Joins ou Apply, etc.) après l'instruction select car la sous-requête factice force l'utilisation de la clause FROM sans modifier le résultat.

DomingoR
la source
1
Vous avez toujours un SELECTsans a FROMdans votre sous-requête, il échouera donc toujours dans Oracle, etc.
Pere
Dans Oracle, c'est encore plus simple car vous pouvez simplement SELECT 'Hello' FROM dual WHERE 1=1ignorer la sous-requête.
DomingoR
Le PO a demandé s'il était possible d'avoir une déclaration (à savoir, a SELECT) sans FROMclause. N'avez-vous pas lu la question?
Pere
J'ai lu la question, mais à moins que vous ne soyez totalement inexpérimenté en SQL (ou que vous n'ayez pas lu d'autres réponses), vous savez que vous ne pouvez pas vous en WHEREpasser FROM. Compte tenu de cela, j'ai répondu à la première déclaration de la question du PO.
DomingoR
Eh bien, j'ai plus de 15 ans d'expérience en SQL, un diplôme en informatique et je ne me souviens pas si avoir maintenant un WHERESQL standard. J'ai lu d'autres réponses aussi. Au fait: la bonne chose est que vous ne pouvez pas avoir un SELECTsans unFROM , pas un WHEREsans FROM(?) Où fonctionne votre requête, @DomingoR? Il a toujours un SELECTsans a FROM(dans la sous-requête), échouant ainsi sur les SGBD qui ne permettent pas d'avoir des requêtes sans a FROMet de travailler uniquement sur celles qui s'écartent du SQL standard et permettent de ne pas avoir FROMde SELECT. Donc votre réponse ne sert à rien.
Pere
0

J'utilise Firebird Tout d'abord, créez une table à une colonne nommée "NoTable" comme ceci

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

maintenant tu peux écrire ça

select 'hello world' as name

de notable

vous pouvez ajouter n'importe quelle colonne que vous souhaitez afficher

Yous Athmane
la source
0

Pour DB2:

`VALUES('Hello world')`

Vous pouvez également créer plusieurs "lignes":

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

Vous pouvez même les utiliser dans les jointures tant que les types correspondent:

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