微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我刚刚浏览了这个 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_clause或hierarchical_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语法:

原文地址:https://www.jb51.cc/mssql/76872.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐