前言
遇到一种奇怪的状况:
对某个View 进行查询时,加条件比不加条件找到的数据还要多。
类似:
select * from view; 找到 1条数据
select * from view where XX=XXX; 却找到了10 条数据。
这看上去是一件毁“三观”的状况。
无庸置疑,原因肯定是出在View 的定义上了。 这个View 的定义唯一特殊的地方是使用了wm_concat 这个函数。
简化重现
为了更好的分析这个问题, 简化的重现一下状况:
暂且以三国的战争列表为例。(数据是瞎诌的)
1. 定义一张表
create table WAR_LIST
(
WAR_NAME varchar2(40),
WAR_TIME date,
WAR_PARTIES varchar2(40)
);
定义了战争名称,发生时间和一个随意的名称(姑且认为是参与方吧)
2. 添加数据
insert into WAR_LIST(WAR_NAME,WAR_TIME,WAR_PARTIES) values('CHIBI',sysdate,'THREE.KINGDOM1.CITY');
insert into WAR_LIST(WAR_NAME,WAR_TIME,WAR_PARTIES) values('CHIBI',sysdate,'THREE.KINGDOM2.CITY');
insert into WAR_LIST(WAR_NAME,WAR_TIME,WAR_PARTIES) values('CHIBI',sysdate,'THREE.KINGDOM9.CITY');
insert into WAR_LIST(WAR_NAME,WAR_TIME,WAR_PARTIES) values('CHIBI',sysdate,'THREE.KINGDOM5.CITY');
insert into WAR_LIST(WAR_NAME,WAR_TIME,WAR_PARTIES) values('CHIBI',sysdate,'THREE.KINGDOM6.CITY');
3. 搜索数据
select distinct T1.WAR_NAME,TO_CHAR(T2.WAR_TIME,'YYYY/MM') AS YEAR_NONTH,T1.A2,'AllParties' as type from
(select WAR_NAME,wm_concat(WAR_PARTIES) as A2 from WAR_LIST group by WAR_NAME) T1
inner join WAR_LIST T2 on T1.WAR_NAME=T2.WAR_NAME where TO_CHAR(T2.WAR_TIME,'YYYY/MM')= '2013/11';
这个SQL 只是把参与方, 汇总了一下。
期望的是找到一条数据, 但是结果却如下:
看上去使用 wm_concat 合并的结果顺序会不一样。
如果使用这种SQL 去创建View 的话, 肯定会出现前言所描述的状况。
结言
1. 如果concat 栏位的值比较简单的话, 出现以上状况的几率看上去比较小。
2. 定义View 的时候需要慎重使用wm_concat 了