选择一无所有?


90

是否有可能这样的声明

SELECT "Hello world"
WHERE 1 = 1

在SQL中?

我想知道的主要事情是,我可以从无中进行选择,即没有FROM子句。


3
查看您对@Rafael Belliard的评论,您最好问问自己真正想做什么。例如,如果给定表中存在值,是否要返回一些字符串?
Jim L

是的,这正是我想要的。我知道我可以做到,我更想知道是否需要FROM NULL介于SELECT和之间WHERE。措辞模糊不清主要是因为这是家庭作业,如果我的直觉不对,我不希望有人来告诉我答案。
Ritwik Bose

Answers:


140

各个供应商之间并不一致-Oracle,MySQL和DB2支持双重:

SELECT 'Hello world'
  FROM DUAL

...而SQL Server,PostgreSQL和SQLite不需要FROM DUAL

SELECT 'Hello world'

MySQL确实支持这两种方式。


2
我一直想知道。为什么为幻象表选择术语对偶?
亚历克斯·布莱克莫尔

5
@Alex:“原始的DUAL表中有两行(因此得名),但随后只有一行。”
rebelliard 2010年

7
在DB2双被称为“SYSIBM.SYSDUMMY1”
多瑙河水手

1
在Postgresql上,可以创建一个称为的虚拟表,DUAL并从类似幻像的表中执行查询。
斯蒂芬

1
@AlexBlakemore“我在Oracle数据字典中创建了DUAL表作为基础对象。它从来都不曾被看到过,而是在预期会被查询的视图中使用。想法是您可以执行JOIN来DUAL表,并为表中的每一行在结果中创建两行,然后,使用GROUP BY,可以汇总结果联接以显示DATA扩展区和INDEX扩展区的存储量。这个名字,DUAL,似乎容易创建一对从只有一个行的过程”(en.wikipedia.org/wiki/DUAL_table
单击确定


14

试试这个。

单:

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

多:

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

此处有更多详细信息:http : //modern-sql.com/use-case/select-without-from


1
唯一符合ANSI SQL的答案!(针对未指定dbms的问题。)
jarlh

目的是WHERE 1 = 1什么?在PostgreSQL上可以不使用它。还是涉及另一个DMBS?
弗兰基·德雷克

只是SELECT * FROM (VALUES ("Hello world")) t1 (col1)还好。Where只是回答这个问题。
chuongtv

@chuongtv如何选择多行?
赫克托

@Hector只需遵循SQL的结构插入。像这样SELECT * FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1
chuongtv

8

这是https://blog.jooq.org/tag/dual-table/中对dual的数据库支持的最完整列表:

在许多其他RDBMS中,不需要虚拟表,因为您可以发出以下语句:

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

这些是RDBMS,通常可以在其中实现:

  • H2
  • 的MySQL
  • 英格利斯
  • Postgres
  • SQLite的
  • SQL服务器
  • Sybase ASE

在其他RDBMS中,需要伪表,例如在Oracle中。因此,您需要编写如下内容:

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

这些是RDBMS及其各自的虚拟表:

  • DB2:SYSIBM.DUAL
  • 德比:SYSIBM.SYSDUMMY1
  • H2:可选地支持DUAL
  • HSQLDB:INFORMATION_SCHEMA.SYSTEM_USERS
  • MySQL:可选地支持DUAL
  • 甲骨文:双
  • Sybase SQL Anywhere:SYS.DUMMY

Ingres没有DUAL,但是实际上将需要DUAL,因为在Ingres中,如果没有FROM子句就不能拥有WHERE,GROUP BY或HAVING子句。


6

在SQL Server中,输入:

Select 'Your Text'

不需要FROMorWHERE子句。


5

您可以。我在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

数据交换使用Transact-SQL(SQL Server对SQL的专有扩展)。

您可以运行以下查询来自己尝试:

SELECT 'Hello world'

数据交换是基于SQL Server的Azure。
OMG小马

2

我认为这是不可能的。从理论上讲:select执行两种操作:

  • 缩小/拓宽集合(集合理论);

  • 映射结果。

可以将第一个视为水平递减,而将位置从句视为垂直递减。另一方面,联接可以水平扩展集合,而联合可以垂直扩展集合。

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

第二个是映射。映射,更多的是一个转换器。在SQL中,它需要一些字段并返回零个或多个字段。在选择中,您可以使用一些聚合函数,例如sum,avg等。或者将所有columnvalues转换为字符串。在C#linq中,我们说select接受类型为T的对象并返回类型为U的对象。

我想混淆的来源的事实,你可以这样做:select 'howdy' from <table_name>。此功能是映射,是转换器的部分选择。您不是在打印什么,而是在转换!在您的示例中:

SELECT "
WHERE 1 = 1

您将无/空转换为空"Hello world",并将无/无表的集合缩小为一行,恕我直言,这毫无意义。

您可能会注意到,如果不限制列数,"Hello world"则会为表中的每个可用行打印。希望您现在明白了。您的选择不会从可用列中获取任何内容,并使用以下文本创建一列:"Hello world"

所以,我的回答是“否”。您不能只保留从句,因为select始终需要表列来执行。


2

在标准SQL中,不。甲WHERE子句意味着表表达式。

根据SQL-92规范:

7.6“ where子句”

功能

指定一个表,该表是通过对前面的“ from子句”的结果应用“搜索条件”而得出的。

反过来:

7.4“ from子句”

功能

指定从一个或多个命名表派生的表。

一种标准的实现方式(即,可以在任何SQL产品上运行):

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

...假设您想将该WHERE子句更改为更有意义的内容,否则可以将其省略。


错误:列的“Hello World”,在MY_TABLE查询不存在失败的PostgreSQL说:列的“hello world”不存在MY_TABLE
帕尔Brattberg

@PålBrattberg:应该是单引号,现在已修复。
一天,2016年

在处理时间上使用哪个表有关系吗?还是SELECT不引用任何列的事实使实际表无关紧要?
艾伦·古尔德

@AllenGould:“依赖于供应商”,但是存在明显的短路可以利用,例如,一种情况是优化器识别该SELECT子句仅包含常量,并且这AnyTableWithOneOrMoreRows是一个存储表,因此仅使用统计信息来验证该表是否具有零行。
一天

2

还有另一种可能性-独立VALUES()

VALUES ('Hello World');

输出:

column1
Hello World

当您需要以紧凑的方式指定多个值时,这很有用:

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

输出:

column1     column2
      1     a
      2     b
      3     c

DBFiddle演示

SQLite / PostgreSQL / DB LUW / MariaDB 10.3支持此语法。


2

对于ClickHouse,没有什么是 system.one

SELECT 1 FROM system.one

1

在Firebird中,您可以执行以下操作:

select "Hello world" from RDB$DATABASE;

RDB $ DATABASE是一个特殊表,始终有一行。


0

我知道这是一个老问题,但是针对您问题的最佳解决方法是使用虚拟子查询:

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

这样,由于伪子查询强制使用FROM子句而不更改结果,因此select语句之后可以具有WHERE和任何子句(如Joins或Apply等)。


1
你还有SELECT没有FROM在你的子查询,所以它会在Oracle等仍未
佩雷

在Oracle中甚至更简单,因为您可以SELECT 'Hello' FROM dual WHERE 1=1跳过子查询。
DomingoR

OP询问是否可以有SELECT不带FROM子句的语句(即a )。你没看问题吗?
佩雷

我确实读过这个问题,但是除非您对SQL完全没有经验(或没有阅读其他答案),否则您将知道您将无法WHERE没有FROM。鉴于此,我回答了OP问题的第一句话。
DomingoR

好吧,我有超过15年的SQL(计算学位)经验,不记得现在是否有WHERE标准SQL。我也阅读其他答案。顺便说一句:正确的事情是,你不能有一个SELECT没有FROM,不是“WHEREFROM”(?)。您的查询在哪里工作,@ DomingoR?它仍然有一个SELECT不带a的FROM(在子查询中),因此在那些不允许不带a的查询的DBMS上失败,FROM并且仅对那些偏离标准SQL并且不允许FROMin的DBMS起作用SELECT。因此,您的答案毫无用处。
佩雷

0

我正在使用firebird首先,像这样创建一个名为“ NoTable”的单列表

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

现在你可以写这个

select 'hello world' as name

从显着

您可以添加任何要显示的列


0

对于DB2:

`VALUES('Hello world')`

您还可以执行多个“行”:

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

只要类型匹配,您甚至可以在联接中使用它们:

VALUES(1,'Hello world')
UNION ALL
VALUES(2,'Goodbye world');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.