[Oracle] 别被View 整伤了

前言

遇到一种奇怪的状况:

对某个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 了



你可能感兴趣的:([Oracle] 别被View 整伤了)