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

sql – 带有SubQueries和Group Functions的Oracle-Bug

任何人都可以解释为什么以下查询返回两行而不只是一行?
SELECT *
  FROM (SELECT 'ASDF' c1,MAX (SUM (1)) c2
          FROM DUAL
         GROUP BY dummy
        UNION
        SELECT 'JKLÖ' c1,1 c2
          FROM DUAL)
 WHERE c1 != 'ASDF';

--another Version with the same wrong result:
SELECT *
  FROM (SELECT 1 c1,MAX (SUM (1)) c2
          FROM DUAL
         GROUP BY dummy
        UNION all
        SELECT 2 c1,1 c2
          FROM DUAL)
 WHERE c1 != 1;

Oracle提供两行是否正确?在我看来,c1 = ASDF的行不应该在结果中.

以下是第一个查询结果的屏幕截图:

我在以下版本上测试了它,总是得到相同的结果:

> Oracle Database 11g企业版11.2.0.3.0版 – 64位生产
> Oracle Database 12c企业版12.1.0.2.0版 – 64位生产

解决方法

不,这不是一个错误.聚合函数是您看到此意外结果的原因.下面是它的工作原理.如果查询没有返回任何行,则SUM()函数以及MAX()函数将返回NULL(产生1行).当您执行查询时,优化器应用谓词推送转换,并且您的原始查询将变为(不会发布整个跟踪,仅发布已转换的查询):
SELECT "from$_subquery$_001"."C1" "C1","from$_subquery$_001"."C2"  "C2" 
   FROM  ( 
           (SELECT 'ASDF' "C1",MAX(SUM(1)) "C2" 
              FROM "SYS"."DUAL" "DUAL" 
             WHERE 'ASDF'<>'ASDF'       [1]-- predicate pushed into the view 
             GROUP BY "DUAL"."DUMMY" )
             UNION 
            (SELECT 'JKLÖ' "C1",1 "C2" 
              FROM "SYS"."DUAL" "DUAL" 
             WHERE 'JKLÖ'<>'ASDF')) "from$_subquery$_001"

[1]由于谓词推送你的第一个查询没有返回任何行,当一个聚合函数(除了count和其他几个),MAX或SUM或者甚至两者都在这个情况下用于空结果集NULL时将返回 – 1行第二个子查询返回1行,从而生成您正在查看的2行结果集.

这是一个简单的演示:

create table empty_table (c1 varchar2(1));

select 'aa' literal,nvl(max(c1),'NULL') as res
  from empty_table

LIteraL RES 
------- ----
aa      NULL

1 row selected.

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

相关推荐