急求助!字符串分解并重新关联的问题

yy2001 2008-01-16 04:12:37
表a:
AID Industry
01C001 1
01C000 2
01C003 2
02C001 3
这样的结构,一个Industry可以对应多个AID
表b:
id Menu_List
490 01C001|01C003|
123 01C001|01C003|01C004|
111 01C004|
Menu_List由a表的AID组成,各个菜单项之间以”|”线分隔;
现在想知道b表中的每条数据的Menu_List中存在多少个a表的Industry,请问如何实现?谢谢!

...全文
341 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
yy2001 2008-01-21
  • 打赏
  • 举报
回复
感谢大家的热心帮助,现在由于数据有点问题,测试不了了,先把帖子解了,有问题再请教大家
bjt_ 2008-01-20
  • 打赏
  • 举报
回复
又或者是b表里的字段过多?,建一个id Menu_List 的复合索引试试
bjt_ 2008-01-20
  • 打赏
  • 举报
回复
把执行计划贴出来看看,是不是连接顺序有问题?
prcgolf 2008-01-18
  • 打赏
  • 举报
回复
up
rouqu 2008-01-18
  • 打赏
  • 举报
回复
B表不作处理的话 6楼的办法应该最简单了
现在性能这么低 就像上面说的 把B表处理下吧
多壮志 2008-01-18
  • 打赏
  • 举报
回复
我不知道你的A表的industry和b表的id有什么关系,假设没有.
属于不算很复杂的问题,29楼的其实基本可以,只要稍微改进以下,要注意到一个industry是可以对应比较多aid的。
所以可以这样修改:
 Select   Menu_List,(Select   Count(aid)  
From (select distinct aid from a) T1
Where INSTR(T2.Menu_List,AID) > 0) FROM T2



最后,如果你的这个查询如果是用于一个查询的应用中,这样的设计是非常错误,非常不合格的。把压力分担到无数个小操作中应该是比较基本的原则,你可以在修改menu_list的同时就计算个数(可以增加一个字段)。
这样,你最终只要对b表来个full scan 就可以了,现在就算最简洁的sql,你也要做一个有点恐怖的scan,焉能不慢?
yy2001 2008-01-18
  • 打赏
  • 举报
回复
多谢各位,我再试试,我不想写成过程,以为最终的语句也是要配到tcl脚本中的

Croatia :
A表里面的数据,有没有这样的状况?
01C001
01C01
01C011

没有,长度是固定的
Croatia 2008-01-18
  • 打赏
  • 举报
回复
Select Menu_List,(Select Count(Industry) From T1 Where INSTR(T2.Menu_List,AID) > 0) FROM T2

我写了这样的句子。
看看效果呢?

我在表T1上面,分别对AID,Industry建立了索引.
T1表1000条数据,T1表1百万条数据的情况下,用了大约30分钟。

数据库是10G的。
Croatia 2008-01-17
  • 打赏
  • 举报
回复
这样的表结构,现在也想不出什么太好的方法了。

可以的话,建议一个函数索引,应该会提升一下速度的。

楼主的数据量大概是多少呢?

Croatia 2008-01-17
  • 打赏
  • 举报
回复
AID都是固定了6位的嘛?
搂主现在大概有多少条数据呢?两个表各有多少呢?
yy2001 2008-01-17
  • 打赏
  • 举报
回复
太慢了,现在还没出来呢,我还加了8个并行呢,有没有效率高些的啊,一会我再试试replace的
wangzk0206 2008-01-17
  • 打赏
  • 举报
回复
用6楼的like就应该可以了
SQL> select distinct a.id from a,b
2 where length(replace(b.addr,a.num))<>length(b.addr);

LENGTH(REPLACE(B.ADDR,A.NUM)) ADDR NUM ID ID
----------------------------- ------------------------------ -------------------- ---------- -------
8 c20001|c30001| c20001 1 232
7 c2002|c20001| c20001 1 233
14 c20001|c30001|c3004| c20001 1 235
8 c2002|c20001| c2002 1 233
8 c20001|c30001| c30001 2 232
14 c20001|c30001|c3004| c30001 2 235
1 c3004| c3004 3 234
15 c20001|c30001|c3004| c3004 3 235

已选择8行。

SQL> select * from a;

ID NUM
---------- --------------------
1 c20001
1 c2002
2 c30001
3 c3004

SQL> select * from b;

ID ADDR
---------- ------------------------------
232 c20001|c30001|
233 c2002|c20001|
234 c3004|
235 c20001|c30001|c3004|

SQL>
用replace也可以
对于这个我还是推荐用过程来实现 因为那样可以确定是完全正确
像用一个SQL的有点担心它的准确度
Croatia 2008-01-17
  • 打赏
  • 举报
回复
A表里面的数据,有没有这样的状况?
01C001
01C01
01C011
Croatia 2008-01-17
  • 打赏
  • 举报
回复
赫赫,之前用length,replace的做法,没有问题的。
他就是把A表的纪录,一个一个检索。
比如说,
01C001 在Menu_List里面出现的话,长度就变了。
然后检索
01C000 没有出现的话,长度就没有变。

差不多等于A表的纪录,都去B里面检索了一次,然后Count.

这是一个对这个问题比较常见的想法。赫赫。

在一个A表数据量 * B表数据量 的笛卡尔积里面运算。你的B里面有百万条,要算上一段时间了。赫赫。

¦?是什么符号?赫赫
kinglht 2008-01-17
  • 打赏
  • 举报
回复
用replace替换|可以实现楼主的要求!
yy2001 2008-01-17
  • 打赏
  • 举报
回复
测试中,按楼上老大的语句,现在已经跑了快1个小时了.
mantisXF 2008-01-17
  • 打赏
  • 举报
回复

XD,下面是两种方法,第一种方法(我最先写的那个)优化了一下,第二种方法是与第一种方法不同的思路,我试了一下第二种的方法速度快一些,你可以试一下看 ..

然后相关字段建索引 .. Just try it ..



SQL> select distinct
2 new_Industry
3 from (
4 select decode(sign(instr('|'||Menu_List,AID,1,rn)),1,Industry,0) as new_Industry
5 from B,
6 A,
7 T
8 where instr('|'||Menu_List,'|',1,rn+1)-instr('|'||Menu_List,'|',1,rn) > 0
9 )tt
10 where new_Industry > 0;

NEW_INDUSTRY
------------
1
2

SQL>
SQL> select distinct
2 Industry
3 from A,
4 (
5 select B.id,
6 substr('|'||Menu_List,
7 instr('|'||Menu_List,'|',1,rn)+1,
8 instr('|'||Menu_List,'|',1,rn+1)-instr('|'||Menu_List,'|',1,rn)-1) as new_Industry
9 from B,
10 tt
11 where instr('|'||Menu_List,'|',1,rn+1)-instr('|'||Menu_List,'|',1,rn) > 0
12 )AB
13 where A.AID = AB.new_Industry;

INDUSTRY
----------
1
2

liuyi8903 2008-01-17
  • 打赏
  • 举报
回复
把内容帖全一点吧,数据量情况,表结构.
Eric_1999 2008-01-17
  • 打赏
  • 举报
回复
需要过程的话再找我。写一句sql太恐怖樂。
Eric_1999 2008-01-17
  • 打赏
  • 举报
回复
要把b表的记录拆分成一个个,然后去a表找有几条对应得记录,再sum求和,就是了,最好用过程实现,一句sql语句很难写出了,就算写出了也不好理解。
加载更多回复(16)

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧