这适用于最有可能出现在 StackOverflow/dba.stackexchange 上的主要关系数据库管理系统,包括SQL Server、MySQL、PostgreSQL 和 SQLite (WebSQL)。
select 'abc' abc, 1 def;
Run Code Online (Sandbox Code Playgroud)
它不适用于 Oracle。为什么我们需要在Oracle中选择DUAL?SQL 的 ISO/ANSI 标准是否要求SELECT语句的 FROM 子句?
根据Bacon Bit
的回答,它似乎是 SQL 标准所要求的。
所以实际上,因为名称 DUAL 用词不当,如果我要创建一个表并将其命名为 ATOM 或 ONE,例如create table one (atom int);
.. select 'abc' abc, 1 def FROM one;
- 与 相比是否有性能损失SELECT .. FROM DUAL
?
Bac*_*its 30
严格地说,是的,语句的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]
Run Code Online (Sandbox Code Playgroud)
在实际使用中,程序员和 DBA 经常会发现,除了操作表中的数据或操作表和数据结构之外,还可以做一些有用的事情。这类事情很大程度上超出了 SQL 标准的范围,SQL 标准更关心数据特征,而不是具体实现的细节。无论我们想要运行SELECT getdate()
orSELECT 1
或SELECT DB_NAME()
(或任何您的方言喜欢的),我们实际上并不想要表中的数据。
Oracle 选择使用具有以下有效定义的虚拟表来解决标准和实现差异:
CREATE TABLE DUAL (
DUMMY CHAR(1)
)
INSERT INTO DUAL (DUMMY) VALUES ('X')
Run Code Online (Sandbox Code Playgroud)
如果没有FROM
指定,其他 RDBMS 基本上假设使用一个虚拟表。
DUAL 表由 Oracle 公司的 Charles Weiss 创建,用于提供用于加入内部视图的表:
我创建了 DUAL 表作为 Oracle 数据字典中的基础对象。它本身并不意味着被看到,而是在预期被查询的视图中使用。这个想法是您可以对 DUAL 表执行 JOIN 并在结果中为表中的每一行创建两行。然后,通过使用 GROUP BY,可以汇总结果连接以显示 DATA 盘区和 INDEX 盘区的存储量。名称 DUAL 似乎适合仅从一个行创建一对行的过程。
原始的 DUAL 表中有两行(因此得名),但随后它只有一行。
优点dual
是优化器理解的dual
是一个特殊的单行单列表(具有varchar2
数据类型)——当您在查询中使用它时,它会在制定计划时使用这些知识。
为什么我们需要dual
在Oracle中选择?
dual
如果需要,您也可以从自己的表中进行选择或从自己的表中进行选择。
对我来说,我会坚持,dual
因为我知道dual
存在。我知道它至少有 1 行,最多有 1 行。我知道优化器对我了如指掌dual
,并为我做了最有效的事情。优化器理解的dual
是一个神奇的、特殊的 1 行表。它停在了select *
因为那里将有一排。所以这就是它的工作方式。
归档时间: |
|
查看次数: |
6498 次 |
最近记录: |