SELECIONE do nada?

94

É possível ter uma declaração como

SELECT "Hello world"
WHERE 1 = 1

em SQL?

A principal coisa que eu quero saber é se posso selecionar do nada, ou seja, não ter uma cláusula FROM.

Ritwik Bose
fonte
3
Olhando seu comentário sobre @Rafael Belliard, talvez seja melhor perguntar o que você realmente quer fazer. Você deseja retornar alguma string se existirem valores para uma determinada tabela, por exemplo?
Jim L
Sim, era exatamente isso que eu queria. Eu sei que posso fazer isso, eu estava mais me perguntando se eu precisava de um FROM NULLentre SELECTe WHERE. Frase obscura principalmente porque é um dever de casa e eu não queria que alguém viesse e me dissesse a resposta se meu pressentimento estivesse errado.
Ritwik Bose,

Respostas:

143

Não é consistente entre os fornecedores - Oracle, MySQL e suporte duplo de DB2:

SELECT 'Hello world'
  FROM DUAL

... embora SQL Server, PostgreSQL e SQLite não exijam FROM DUAL:

SELECT 'Hello world'

O MySQL oferece suporte para as duas formas.

Pôneis OMG
fonte
3
Sempre me perguntei. Por que escolher o termo dual para a mesa fantasma?
Alex Blakemore
5
@Alex: "A tabela DUAL original tinha duas linhas (daí seu nome), mas subsequentemente só tinha uma linha."
rebelde de
8
No DB2, o dual é chamado 'sysibm.sysdummy1'
Danubian Sailor
1
No Postgresql, é possível criar uma tabela fictícia chamada DUALe realizar consultas a partir de uma tabela semelhante a um fantasma.
Stephan
1
@AlexBlakemore "Eu criei a tabela DUAL como um objeto subjacente no Dicionário de dados Oracle. Ela nunca foi feita para ser vista, mas sim usada dentro de uma visão que deveria ser consultada. A ideia era que você pudesse fazer um JOIN para a tabela DUAL e criar duas linhas no resultado para cada linha em sua tabela. Em seguida, usando GROUP BY, a junção resultante pode ser resumida para mostrar a quantidade de armazenamento para a extensão DATA e para a (s) extensão (ões) INDEX. O nome, DUAL, parecia adequado para o processo de criação de um par de linhas a partir de apenas uma "( en.wikipedia.org/wiki/DUAL_table )
Clique em Ok
29

No Oracle :

SELECT 'Hello world' FROM dual

Equivalente duplo no SQL Server :

SELECT 'Hello world' 
rebelde
fonte
1
Posso colocar uma declaração assim WHERE (SELECT ... )depois disso?
Ritwik Bose,
16

Experimente isso.

Solteiro:

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

mais detalhes aqui: http://modern-sql.com/use-case/select-without-from

Chuongtv
fonte
1
A única resposta compatível com ANSI SQL! (Para uma pergunta sem dbms especificado.)
jarlh
Qual é o propósito de WHERE 1 = 1? No PostgreSQL funciona sem ele. Ou se trata de outro DMBS?
Frankie Drake
SELECT * FROM (VALUES ("Hello world")) t1 (col1)ainda multar. Whereapenas responda para esta pergunta.
chuongtv
@chuongtv Como você seleciona várias linhas?
Hector
@Hector Basta seguir a inserção de estrutura do SQL. assimSELECT * FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1
chuongtv
8

Aqui está a lista mais completa de suporte a banco de dados dual de https://blog.jooq.org/tag/dual-table/ :

Em muitos outros RDBMS, não há necessidade de tabelas fictícias, pois você pode emitir instruções como estas:

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

Estes são os RDBMS, onde o acima é geralmente possível:

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

Em outros RDBMS, tabelas fictícias são necessárias, como no Oracle. Portanto, você precisará escrever coisas como estas:

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

Estes são o RDBMS e suas respectivas tabelas fictícias:

  • DB2: SYSIBM.DUAL
  • Derby: SYSIBM.SYSDUMMY1
  • H2: opcionalmente, oferece suporte a DUAL
  • HSQLDB: INFORMATION_SCHEMA.SYSTEM_USERS
  • MySQL: opcionalmente compatível com DUAL
  • Oracle: DUAL
  • Sybase SQL Anywhere: SYS.DUMMY

Ingres não tem DUAL, mas na verdade precisa dele, pois em Ingres você não pode ter uma cláusula WHERE, GROUP BY ou HAVING sem uma cláusula FROM.

Vadzim
fonte
6

No tipo de servidor SQL:

Select 'Your Text'

Não há necessidade da cláusula FROMou WHERE.

RollTide
fonte
5

Você pode. Estou usando as seguintes linhas em uma consulta do 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

O Data Exchange usa Transact-SQL (as extensões proprietárias do SQL Server para SQL).

Você pode tentar por si mesmo executando uma consulta como:

SELECT 'Hello world'
palswim
fonte
O Data Exchange é Azure, baseado em SQL Server.
Pôneis OMG,
2

Eu acho que não é possível. Teoricamente: select executa dois tipos de coisas:

  • estreitar / ampliar o conjunto (teoria dos conjuntos);

  • mapeando o resultado.

O primeiro pode ser visto como uma diminuição horizontal em oposição à cláusula where, que pode ser vista como uma diminuição vertical. Por outro lado, uma união pode aumentar o conjunto horizontalmente, enquanto uma união pode aumentar o conjunto verticalmente.

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

O segundo é um mapeamento. Um mapeamento, é mais um conversor. No SQL, leva alguns campos e retorna zero ou mais campos. No select, você pode usar algumas funções de agregação, como sum, avg etc. Ou pegar todos os valores de coluna e convertê-los em string. Em C # linq, dizemos que um select aceita um objeto do tipo T e retorna um objeto do tipo U.

Eu acho que a confusão vem do fato de que você pode fazer: select 'howdy' from <table_name>. Esse recurso é o mapeamento, a parte conversora do select. Você não está imprimindo algo, mas convertendo! No seu exemplo:

SELECT "
WHERE 1 = 1

você está convertendo nada / nulo em "Hello world"e restringe o conjunto de nada / nenhuma tabela em uma linha, o que, na verdade, não faz sentido algum.

Você pode notar que, se você não restringir o número de colunas, "Hello world"é impresso para cada linha disponível na tabela. Espero que você entenda o porquê agora. A sua escolha não leva nada de colunas disponíveis e cria uma coluna com o texto: "Hello world".

Portanto, minha resposta é NÃO. Você não pode simplesmente deixar de fora a cláusula from porque o select sempre precisa de colunas de tabela para executar.

Andries
fonte
2

No SQL padrão, não. Uma WHEREcláusula implica uma expressão de tabela.

Da especificação SQL-92:

7.6 "cláusula where"

Função

Especifique uma tabela derivada da aplicação de uma "condição de pesquisa" ao resultado da "cláusula de" anterior.

Por sua vez:

7.4 "da cláusula"

Função

Especifique uma tabela derivada de uma ou mais tabelas nomeadas.

Uma maneira padrão de fazer isso (ou seja, deve funcionar em qualquer produto SQL):

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

... presumindo que você deseja alterar a WHEREcláusula para algo mais significativo, caso contrário, ela pode ser omitida.

um dia quando
fonte
ERRO: a coluna "hello world" não existe em minha_tabela Falha na consulta PostgreSQL disse: a coluna "hello world" não existe em minha_tabela
Pål Brattberg
@ PålBrattberg: devem ser aspas simples, agora corrigidas.
um
Faz diferença qual tabela é usada em termos de tempo de processamento? Ou o fato de SELECT não fazer referência a nenhuma das colunas torna a tabela real irrelevante?
Allen Gould
@AllenGould: seria 'dependente do fornecedor', mas existem curtos-circuitos óbvios que poderiam ser explorados, por exemplo, um caso é onde o otimizador reconhece que a SELECTcláusula compreende apenas constantes e isso AnyTableWithOneOrMoreRowsé uma tabela armazenada, portanto, apenas usa estatísticas para verificar se a tabela tem zero linhas.
dia em
2

Existe outra possibilidade - independente VALUES():

VALUES ('Hello World');

Resultado:

column1
Hello World

É útil quando você precisa especificar vários valores de forma compacta:

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

Resultado:

column1     column2
      1     a
      2     b
      3     c

DBFiddle Demo

Esta sintaxe é compatível com SQLite / PostgreSQL / DB LUW / MariaDB 10.3.

Lukasz Szozda
fonte
2

Para ClickHouse, o nada é system.one

SELECT 1 FROM system.one
simPod
fonte
1

No Firebird, você pode fazer isso:

select "Hello world" from RDB$DATABASE;

RDB $ DATABASE é uma tabela especial que sempre possui uma linha.

Robyn
fonte
0

Eu sei que esta é uma pergunta antiga, mas a melhor solução para sua pergunta é usar uma subconsulta fictícia:

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

Desta forma, você pode ter WHERE e qualquer cláusula (como Joins ou Apply, etc.) após a instrução select, uma vez que a subconsulta fictícia força o uso da cláusula FROM sem alterar o resultado.

DomingoR
fonte
1
Você ainda tem um SELECTsem um FROMem sua subconsulta, então ele ainda falhará no Oracle etc.
Pere
No Oracle é ainda mais simples porque você pode simplesmente SELECT 'Hello' FROM dual WHERE 1=1pular a subconsulta.
DomingoR
O OP perguntou se era possível ter uma declaração (ou seja, a SELECT) sem uma FROMcláusula. Você não leu a pergunta?
Pere
Eu li a pergunta, mas a menos que você seja totalmente inexperiente em SQL (ou não tenha lido outras respostas), você sabe que não pode WHEREsem FROM. Diante disso, respondi à primeira declaração da pergunta do OP.
DomingoR
Bom, tenho mais de 15 anos de experiência em SQL, sou Licenciado em Computação e não lembrava se agora tinha um WHERESQL padrão. Eu li outras respostas também. A propósito: o correto é que você não pode ter um SELECTsem umFROM , não "um WHEREsem FROM" (?). Onde sua consulta funciona, @DomingoR? Ainda tem um SELECTsem FROM(na subconsulta), falhando assim naqueles SGBD que não permitem ter consultas sem um FROMe trabalhando apenas naquelas que se desviam do SQL padrão e permitem não ter um FROMno SELECT. Portanto, sua resposta não serve para nada.
Pere
0

Estou usando o firebird. Em primeiro lugar, crie uma tabela de uma coluna chamada "NoTable" como esta

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

agora você pode escrever isso

select 'hello world' as name

de notável

você pode adicionar qualquer coluna que deseja exibir

Yous Athmane
fonte
0

Para DB2:

`VALUES('Hello world')`

Você também pode fazer várias "linhas":

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

Você pode até mesmo usá-los em junções, desde que os tipos correspondam:

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