严格来说,是的,语句的FROM
子句SELECT
不是可选的。 SQL-99的语法详细说明了基本SELECT
语句,该FROM
子句周围没有方括号。这表明该标准认为它是非可选的:
SELECT [ DISTINCT | ALL ]
{Column expression [ AS name ]} [ ,... ] | *
FROM <Table reference> [ {,<Table reference>} ... ]
[ WHERE search condition ]
[ GROUP BY Columns [ HAVING condition ] ]
[ORDER BY {col_name | expr | position} [ASC | DESC],...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name' export_options |
INTO DUMPFILE 'file_name' |
INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]
在实际使用中,程序员和DBA经常发现除操作表中的数据或操作表和数据结构外,还可以执行其他操作。这种类型的事情在很大程度上超出了SQL标准的范围,SQL标准关注的是数据特性,而不是特定实现的基本要素。无论我们是要运行SELECT getdate()
还是SELECT 1
或SELECT DB_NAME()
(或您的方言喜欢的任何一种),我们实际上都不需要表中的数据。
Oracle选择使用具有以下有效定义的虚拟表来解决标准和实现上的差异:
CREATE TABLE DUAL (
DUMMY CHAR(1)
)
INSERT INTO DUAL (DUMMY) VALUES ('X')
其他RDBMS本质上假设如果未FROM
指定,则使用虚拟表。
DUAL表的历史记录在Wikipedia上:
DUAL表是由Oracle公司的Charles Weiss创建的,用于提供用于内部视图联接的表:
我将DUAL表创建为Oracle数据字典中的基础对象。从来没有想过要看到它本身,而是在期望查询的视图中使用它。想法是您可以对DUAL表进行JOIN并为表中的每一行在结果中创建两行。然后,通过使用GROUP BY,可以汇总结果联接以显示DATA扩展区和INDEX扩展区的存储量。名称DUAL似乎很适合仅从一个行创建一对行的过程。
原始的DUAL表中有两行(因此得名),但随后只有一行。
select
没有from
。DB2有一个类似的伪表,称为SYSIBM.SYSDUMMY1。您可能也已经知道这一点,但是当您使用时select 'A' from dual
,dual
并没有真正访问该表,它会在您的编辑中回答问题(顺便提一个新问题)。