sql - GROUP BY子句之后的Oracle CONNECT BY子句

标签 sql oracle select syntax hierarchical-query

我刚刚遍历了这个interesting article here,展示了如何使用分层查询和窗口函数在Oracle中模拟wm_concat() group_concat() :

SELECT deptno,
       LTRIM(MAX(SYS_CONNECT_BY_PATH(ename,','))
       KEEP (DENSE_RANK LAST ORDER BY curr),',') AS employees
FROM   (SELECT deptno,
               ename,
               ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) AS curr,
               ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) -1 AS prev
        FROM   emp)
GROUP BY deptno
CONNECT BY prev = PRIOR curr AND deptno = PRIOR deptno
START WITH curr = 1;

虽然,我发现这不是一个可读性很强的解决方案,但它非常有趣,特别是因为CONNECT BY .. STARTS WITH子句位于GROUP BY子句之后。根据the specification,这是不可能的。我试过使用一个简单的查询,它的确起作用,但是!以下两个查询返回相同的结果:
-- wrong according to the specification:
select level from dual group by level connect by level <= 2;
-- correct according to the specification:
select level from dual connect by level <= 2 group by level;

这是未记录的功能吗?还是只是为了方便而语法无关紧要?还是这两个语句巧妙地表现出不同?

最佳答案

我认为这只是微不足道的语法差异。

更具体地说,我认为这是一个文档错误。 8i的语法图表示支持任一顺序。 8i reference中的任何内容均不表示顺序有任何不同。但是该图还暗示您可以具有多个group_by_clausehierarchical_query,但事实并非如此:

--You can't group twice: ORA-01787: only one clause allowed per query block
select level from dual connect by level <= 2 group by level group by level;

我的猜测是,当Oracle修复9i的语法图时,他们也忘记了顺序可能会有所不同。或者,也许他们有意地将其遗漏了,因为先执行层次结构部分似乎更合乎逻辑。

像这样的一些较小的语法变体尚未记录。我认为这并不意味着他们不受支持。 Oracle可能会后悔允许这么多怪异的选择,并希望事情至少看起来简单。例如,HAVING可以在GROUP BY之前出现,许多旧的并行功能仍然可以使用(但被忽略),等等。(这就是为什么当人们说他们将快速“解析SQL”时我总是笑着-祝您好运!)

Oracle 8i语法:

Oracle 9i语法:

关于sql - GROUP BY子句之后的Oracle CONNECT BY子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10043445/

相关文章:

java - 在单个类中连接到两个不同的数据库

sql - COMMIT 和 ROLLBACK 之间的开销有区别吗?

matlab - 顺序特征选择 Matlab

sql - 根据自动增量列插入列值

如果分隔符存在,则 SQL 选择子字符串,否则给出完整字符串

mysql - 需要一个 SQL 来获取全年每月和每天的高计数

java - Apple 弃用 Java,我们作为程序员的技术选择是什么?

MySQL:连接多个表时获取重复值

mysql - 使用 mysql 连接表最快的方法是什么

mysql请求检索结合2个表的数据