乍看 ORA-00979 not a GROUP BY expression 这个提示估计很快能将其定位为SQL语句写得有问题,实际上有可能你遇到了一个Oracle的BUG,这个BUG常见于10.2.0.4这个版本(10g最后一个补丁版本是10.2.0.5)。
前几天和同事做一个应用系统升级的时候遇到了这个问题,首先是一张视图无法创建,仔细分析构成视图的查询也没有发现明显的SQL语法问题:
select t.stat_date,
t.species_name,
t.species_id,
0 jzcg_bid_price,
(select nvl(sum(a.bid_price), 0)
from vb_pr_stat27_2 a
where a.stock_mode_name = 'AAAAAAAA'
and a.stat_date = t.stat_date
and a.species_name = t.species_name
and a.stock_mode_name = t.stock_mode_name
group by a.stat_date, a.species_name,a.site_id,a.org_id) gk_bid_price,
(select nvl(sum(a.bid_price), 0)
from vb_pr_stat27_2 a
where a.stock_mode_name = 'BBBBBBBB'
and a.stat_date = t.stat_date
and a.species_name = t.species_name
and a.stock_mode_name = t.stock_mode_name
group by a.stat_date, a.species_name) yq_bid_price,
(select nvl(sum(a.bid_price), 0)
from vb_pr_stat27_2 a
where a.stock_mode_name = 'CCCCCCCC'
and a.stat_date = t.stat_date
and a.species_name = t.species_name
and a.stock_mode_name = t.stock_mode_name
group by a.stat_date, a.species_name) jz_bid_price,
(select nvl(sum(a.bid_price), 0)
from vb_pr_stat27_2 a
where a.stock_mode_name = 'DDDDDDDD'
and a.stat_date = t.stat_date
and a.species_name = t.species_name
and a.stock_mode_name = t.stock_mode_name
group by a.stat_date, a.species_name) xj_bid_price,
(select nvl(sum(a.bid_price), 0)
from vb_pr_stat27_2 a
where a.stock_mode_name = 'EEEEEEEE'
and a.stat_date = t.stat_date
and a.species_name = t.species_name
and a.stock_mode_name = t.stock_mode_name
group by a.stat_date, a.species_name) dy_bid_price,
(select nvl(sum(a.bid_price), 0)
from vb_pr_stat27_2 a
where a.stock_mode_name = 'FFFF'
and a.stat_date = t.stat_date
and a.species_name = t.species_name
and a.stock_mode_name = t.stock_mode_name
group by a.stat_date, a.species_name) qt_bid_price,
t.site_id,
t.agency_id,
t.org_id,
t.org_name
from vb_pr_stat27_2 t;
就是死活报 ORA-00979 ,由于这个查询涉及其他视图,其他视图又涉及多张表,一时没有办法拿到其他版本的数据库中测试,并没有意识到这个BUG。
后来我同事在会话级别设定参数 _complex_view_merging 为 false 之后,就没有再报 ORA-00979 了。查阅了一些相关资料,在这位仁兄的blog中找到了对这个BUG的描述,据说10.2.0.5的Fixed Bug List中能找到这个BUG,但是一直搞不到这份List。
以下是基本上就是摘录这位仁兄的内容了,让我们重现一下这个BUG,首先是建表语句,不用测试数据了:
----
CREATE TABLE pers_dinner
(
"PER_ID" NUMBER(10) NOT NULL,
"PERS_DINNER_COUNT" NUMBER(3) NOT NULL,
"PERS_DINNER_DATE" DATE NOT NULL,
"UPD_TS" DATE DEFAULT SYSDATE NOT NULL,
"UPD_UID" NUMBER(10),
"PERS_DINNER_GROUP" CHAR(1 byte) NOT NULL,
"ID" NUMBER(10) NOT NULL,
"STATUS" NUMBER(1)
DEFAULT 9 NOT NULL,
"UCETNI_ROK" NUMBER(4)
DEFAULT to_number(to_char(sysdate,'YYYY')) NOT NULL,
"UCETNI_MESIC" NUMBER(2)
DEFAULT to_number(to_char(sysdate,'MM')) NOT NULL,
CONSTRAINT "PK_PERS_DINNER2"
PRIMARY KEY("ID"),
CONSTRAINT "UQ_PERS_DINNER2"
UNIQUE("PER_ID", "PERS_DINNER_GROUP", "PERS_DINNER_DATE", "UCETNI_ROK")
)
LOGGING
MONITORING;
然后一个比较复杂的查询:
select
xx.ucetni_rok || xx.mesic as id,
xx.ucetni_rok as rok,
xx.mesic,
(
select nvl(sum(d2.pers_dinner_count), 0) as cnt
from pers_dinner d2
where d2.per_id = '27052'
and d2.status in (0, 9)
and d2.pers_dinner_group = 'U'
and d2.ucetni_rok = xx.ucetni_rok
and to_char(d2.pers_dinner_date, 'MM.YYYY') = xx.mesic
) as suma_u
from (
select
d.pers_dinner_group,
d.ucetni_rok,
to_char(d.pers_dinner_date, 'MM.YYYY') as mesic,
sum(d.pers_dinner_count) as cnt
from pers_dinner d
where d.per_id = '112378'
and d.status in (0,9)
group by d.pers_dinner_group, d.ucetni_rok, to_char(d.pers_dinner_date, 'MM.YYYY')
) xx;
马上就会报: ORA-00979: not a GROUP BY expression 了。
如果,将 _complex_view_merging 这个参数设定为 false 就可以马上得到结果。
alter session set "_complex_view_merging"=false ;
在 10gR2 的第一个版本,也就是 10.2.0.1 没有这个问题,所以可以认为是 10.2.0.4 这个补丁包引入的BUG。