今天遇到的一个问题,上午搞大半天硬是没有搞定。郁闷!看来还是经验不够,基础知识不扎实!
表结构大致如下:
Table_A:A_id A_code A_money A_others
1 A001 50 ……
2 A002 60 ……
3 A003 100 ……
4 A004
70 ……
Table_B:B_id B_name B_others A_codes
1 组1 …… A001,A002
2 组2 …… A001,A002,A003
3 组3 …… A002,A003
也就是说Table_B中的A_ids存放的是Table_A的A_code
,现在想通过Table_B中的A_codes来查询出Table_A中对应的内容。比如:求不同的组的金额合计
这个问题因为Table_B “组”是可以任意组合的,并且一开始就指定了产品,现在需要求不同组的金额。
表就设计成了这个样子。
开始的想法很简单。
select sum(A.A_money) money,B.B_id id ,B.B_name name from
Table_A A,Table_B B
where A.A_code in
(B.A_codes) group by B.B_id ,B.B_name
结果这样做是不行的,in后面必须是一个集合,虽然内容格式是一样的,但是验证是无法通过的,因为sql查询的结果是一个具体的值,而不是一个集合,因此这样做是不会报错,但是记录数是0.
后来就一直在想办法拆分这些逗号,怎样分解,将值转化为集合,但是始终没有好的解决办法。
最好看到函数有个instr
select sum(A.A_money) money,B.B_id id ,B.B_name name from
Table_A A,Table_B B
where instr(B.A_codes,A.A_code)>0
group by B.B_id ,B.B_name
OK!终于搞定!
不过这个问题也有特殊性,就是这些编号没有子包含的问题。
如果是动态id,就不能用这个来处理了。比如说ID可能为:1,11,111,2,20,200 那统计的数据肯定会出错。
如果是有子包含的情况,可以这样写:
select B.id A.A_content from
Table_A A ,Table_B B where
instr(','||B.A_ids||',',
',' || A.id ||',')>0 group by B.id
这样写应该不会有漏洞。编号中总不能含有逗号的。
不过这只是在数据量不大,偷懒的情况下这样建的表结构。考虑到instr的效率问题,在数据量大的时候,多对一的关系,最好还是不要建这样的表结构。