在 Oracle 中选择不带 FROM 子句

Posted

技术标签:

【中文标题】在 Oracle 中选择不带 FROM 子句【英文标题】:Select without a FROM clause in Oracle 【发布时间】:2010-12-25 07:24:18 【问题描述】:

SQL Server 中可以执行 SELECT,而无需参考表;类似:

Select 1.2 +3, 'my dummy string'

由于 Oracle 不允许没有 FROM 的 SELECT,所以我使用对偶表进行此类操作;类似:

Select 1,2+3, 'my dummy string' FROM DUAL

有更好的方法来进行这种类型的查询吗?使用双表是个好习惯吗?

【问题讨论】:

【参考方案1】:

不,在Oracle 中没有SELECT 没有FROM

使用dual 表是一种很好的做法。

dual 是一个内存表。如果你不从中选择DUMMY,它使用一个特殊的访问路径(FAST DUAL),不需要I/O

曾几何时,dual 有两条记录(因此得名),并打算用作一个虚拟记录集来复制正在连接的记录。

现在它只有一条记录,但您仍然可以使用它生成任意数量的行:

SELECT  level
FROM    dual
CONNECT BY
        level <= 100

mysql 还支持dual(以及 fromless 语法)。

【讨论】:

不知道双重的历史。只要确保 dual 只包含一行。我见过有各种东西的双桌。保证长时间有趣的错误搜索。 有点像 /dev/null 被普通文件替换? @Paul Tomblin:比这更糟。根据您是否从中选择dummy,dual 使用不同的访问路径。 这里有一个来自 Tom Kyte 的很好的链接,它涉及 Dual 的某些方面:asktom.oracle.com/pls/asktom/… 您知道 Oracle 是否考虑过放弃 FROM 子句要求吗?从 dual 中选择对我来说似乎很荒谬和 hacky,我不敢相信 Oracle 从来没有解决过这个问题。【参考方案2】:

不要忘记,大多数时候您实际上并不需要使用 SELECT。

代替:

SELECT sysdate INTO l_date FROM dual;
SELECT CASE WHEN i = j THEN 0 ELSE 1 END INTO l_foo FROM dual;
...

你可以使用

l_date := sysdate;
l_foo  := CASE WHEN i = j THEN 0 ELSE 1 END;
...

【讨论】:

+1 如果您没有从任何表中获取任何数据,请不要执行查询,您可以在 PL/SQL 中完成所有操作。【参考方案3】:

使用对偶是个好习惯 表

是的,双表通常用于此目的。当您没有可供选择的表时,这在 Oracle 中是相当标准的。

【讨论】:

这就是我从不使用 Oracle 的原因。它已经从根本上死了。【参考方案4】:

是的,双表是在 Oracle 中执行此操作的常用方法。其实就是为了这个才引入的。

DUAL 的主要优点是 Oracle 中的优化器知道它是特殊的,因此使用它的查询可以比使用自己创建的单行表更快。除此之外,并没有什么特别之处。

【讨论】:

【参考方案5】:

我认为你必须使用双。当您需要运行没有表名的 SQL 时使用它。我不能说除了在 SQL 脚本中使用它来回显某些东西的运行日期或类似的愚蠢的东西。

【讨论】:

【参考方案6】:

实际上,SQL Server 的实现是非标准的。 SQL-92 Standard(第 7.9 节)需要在 SELECT 语句中使用 FROM 子句。 DUAL 是 Oracle 提供表以从中选择以获取标量行的方式。

【讨论】:

以上是关于在 Oracle 中选择不带 FROM 子句的主要内容,如果未能解决你的问题,请参考以下文章

oracle group by 性能优化

Oracle 优化相关

oracle查询优化

Oracle 性能优化

Oracle 性能优化

Oracle SQL性能优化