使用SQL * Plus 11.2在Oracle Database 11g上运行数据库。是否在WITH子句中不允许使用聚合方法,还是WITH做了一些神奇的事情?这段代码告诉我" most_expensive"是无效的标识符。然而,子查询没有问题。
WITH most_expensive AS (SELECT MAX (enrollment_cost) FROM Enrollments)
SELECT e.member_id
FROM Enrollments e
WHERE e.enrollment_cost = most_expensive;
答案 0 :(得分:3)
查询因子(带子句)允许您定义临时表别名。
在您的示例中,most_expensive将引用包含具有单个列的单个行的表对象。您可以在查询中的任何位置使用它,您可以在其中使用表。
现在,如果你创建一个名为t1的表(使用create table statment),给它一列并插入1行,你仍然无法做到" WHERE x = t1"。
换句话说,子查询并不总是与表相同,而WITH子句为您提供的行为类似于表,而不是像子查询。
以下作品:
WITH most_expensive AS (SELECT MAX (enrollment_cost) FROM Enrollments)
SELECT member_id
FROM Enrollments e
WHERE e.enrollment_cost = (select * from most_expensive);
答案 1 :(得分:1)
我认为在这里使用子查询因子分析(WITH子句)没有任何好处。查询可以简单地写成:
SELECT member_id
FROM Enrollments e
WHERE e.enrollment_cost =
(SELECT MAX (enrollment_cost) FROM Enrollments
);
比较解释计划:
没有子查询保理:
SQL> set autot on explain
SQL> SELECT empno FROM emp e WHERE e.sal =
2 (SELECT MAX (sal) FROM emp
3 );
EMPNO
----------
7839
Execution Plan
----------------------------------------------------------
Plan hash value: 1876299339
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 8 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 8 | 4 (0)| 00:00:01 |
| 2 | SORT AGGREGATE | | 1 | 4 | | |
| 3 | TABLE ACCESS FULL| EMP | 14 | 56 | 4 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("E"."SAL"= (SELECT MAX("SAL") FROM "EMP" "EMP"))
使用子查询保理:
SQL> WITH max_sal AS
2 ( SELECT MAX (sal) sal FROM emp
3 )
4 SELECT empno FROM emp e WHERE e.sal =
5 (SELECT sal FROM max_sal
6 );
EMPNO
----------
7839
Execution Plan
----------------------------------------------------------
Plan hash value: 73843676
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 8 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 8 | 4 (0)| 00:00:01 |
| 2 | VIEW | | 1 | 13 | 4 (0)| 00:00:01 |
| 3 | SORT AGGREGATE | | 1 | 4 | | |
| 4 | TABLE ACCESS FULL| EMP | 14 | 56 | 4 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("E"."SAL"= (SELECT "SAL" FROM (SELECT MAX("SAL") "SAL"
FROM "EMP" "EMP") "MAX_SAL"))
请参阅应用的过滤器,您所做的只是使其嵌套查询并深入一级而不实际添加任何好处。
答案 2 :(得分:0)
您的因子查询(表)名为most_expensive
,但您将其用作列名。在这种情况下,您应该使用keep first
。
SELECT max(member_id) KEEP (DENSE_RANK FIRST ORDER BY enrollment_cost desc nulls last) "Best"
FROM Enrollments e
WHERE e.enrollment_cost = most_expensive;