Oracle - RETURNING与聚合函数相结合

Luk*_*zda 9 sql oracle aggregate-functions sql-returning

Oracle支持RETURNING可能非常有用的子句.

例如对于数据:

CREATE TABLE t(Id INT, Val varchar2(50));

INSERT INTO t(Id, Val)
SELECT 10,'a' FROM dual
UNION ALL SELECT 20,'b' FROM dual
UNION ALL SELECT 30,'a' FROM dual
UNION ALL SELECT 40,'b' FROM dual;
Run Code Online (Sandbox Code Playgroud)

查询:

DECLARE
   l_cnt INT;
BEGIN
   DELETE FROM t RETURNING COUNT(*) INTO l_cnt;
   DBMS_OUTPUT.put_line('l_cnt: ' || l_cnt);
END;
Run Code Online (Sandbox Code Playgroud)

l_cnt:4

它支持MIN/MAX/AVG/SUM/LISTAGG:

DECLARE
   l_max INT;
   l_min INT;
   l_str VARCHAR2(100);
BEGIN
   DELETE FROM t 
   RETURNING MAX(id), MIN(id), LISTAGG(id, ',') WITHIN GROUP(ORDER BY id) 
   INTO l_max, l_min, l_str;
   DBMS_OUTPUT.put_line('l_max:'||l_max||' l_min:'||l_min||' l_str:'|| l_str);
END;
Run Code Online (Sandbox Code Playgroud)

l_max:40 l_min:10 l_str:10,20,30,40

不幸的是,当与DISTINCT关键字结合使用时出现错误:

DECLARE
   l_distinct_cnt INT;
BEGIN
   DELETE FROM t 
   RETURNING COUNT(DISTINCT val) INTO l_distinct_cnt ;
   DBMS_OUTPUT.put_line('l_distinct_cnt:' || l_distinct_cnt );
END;
Run Code Online (Sandbox Code Playgroud)

ORA-00934:此处不允许使用组功能

db <>小提琴演示

问题是为什么DISTINCT不允许使用聚合函数?我正在寻找官方消息来源的答案.


编辑:

请注意,这COUNT(DISTINCT ...)只是一个例子.相同的行为适用于SUM(col)/SUM(DISTINCT col)任何支持DISTINCT关键字的聚合函数.

SUM(val)vs SUM(DISTINCT val)

Jef*_*olt 0

主要原因是 SQL 不可组合。CJ Date 表明,至少在我在北德克萨斯参加的 2009 年课程中,SQL 是不可组合的。因为它不可组合,所以某些东西不是免费的。我所说的免费是指不假思索。但服务器技术领域的人们非常聪明,我确信那些管理“添加返回功能”项目的人有意识地确定了界限。他们显然决定不会“完全”编写解析器。我怀疑这是因为他们知道,如果他们采取 100% 可支持性的立场,那么一旦 SQL 的其他部分得到增强,那么他们也必须花时间增强该语言的其他部分。

我确实很钦佩 ST,因为他们的 SQL 解析器执行速度有多快,而且很少会产生错误结果。但我想知道,如果占主导地位的查询语言至少是可组合的,世界会变得多么美好,但不像戴特先生那样热切。