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:此处不允许使用组功能
问题是为什么DISTINCT不允许使用聚合函数?我正在寻找官方消息来源的答案.
编辑:
请注意,这COUNT(DISTINCT ...)只是一个例子.相同的行为适用于SUM(col)/SUM(DISTINCT col)任何支持DISTINCT关键字的聚合函数.
主要原因是 SQL 不可组合。CJ Date 表明,至少在我在北德克萨斯参加的 2009 年课程中,SQL 是不可组合的。因为它不可组合,所以某些东西不是免费的。我所说的免费是指不假思索。但服务器技术领域的人们非常聪明,我确信那些管理“添加返回功能”项目的人有意识地确定了界限。他们显然决定不会“完全”编写解析器。我怀疑这是因为他们知道,如果他们采取 100% 可支持性的立场,那么一旦 SQL 的其他部分得到增强,那么他们也必须花时间增强该语言的其他部分。
我确实很钦佩 ST,因为他们的 SQL 解析器执行速度有多快,而且很少会产生错误结果。但我想知道,如果占主导地位的查询语言至少是可组合的,世界会变得多么美好,但不像戴特先生那样热切。