我刚刚看到了这篇有趣的文章,它展示了如何使用分层查询和窗口函数在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
子句之后。根据规范,这不应该是可能的。但是,我用一个简单的查询尝试了一下,它确实可以工作!以下两个查询返回相同的结果:
-- 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;
这是一个未记录的特性吗?还是为了方便而采用的语法不同?或者这两个语句微妙地表现出不同的行为?