求sql, 不用存储过程可以实现吧

xlongbuilder 2008-12-25 05:05:18

CREATE OR REPLACE FUNCTION SPLIT (p_list VARCHAR2, p_sep VARCHAR2 := ',')
RETURN type_split PIPELINED
IS
l_idx PLS_INTEGER;
v_list VARCHAR2 (50) := p_list;
BEGIN
LOOP
l_idx := INSTR (v_list, p_sep);

IF l_idx > 0
THEN
PIPE ROW (SUBSTR (v_list, 1, l_idx - 1));
v_list := SUBSTR (v_list, l_idx + LENGTH (p_sep));
ELSE
PIPE ROW (v_list);
EXIT;
END IF;
END LOOP;

RETURN;
END SPLIT;
select * from table(split('bb','aa'));
返回的是一个表的2条数据 bb aa

不过该函数貌似不能解决下面的问题
如表 A 中a字段存了总金额99,userid 字段中存了aa,22,bb 这样的用户id数据,我要把金额平均分配给每个人
A
id userid je
-------
1 aa,22,bb 99
2 dd2,3a 2
........
我如何才能将该数据变成
id userid je
1 aa 33
1 22 33
1 bb 33
2 dd2 1
2 3a 1
........
别说表不合理,因为为了减少数据量 userid中的用户数可能会10几个, 试试看这样的性能如何

...全文
314 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangyong369 2008-12-29
  • 打赏
  • 举报
回复
exec pro_split;

1 aa 33
1 22 33
1 bb 33
2 dd2 1
2 3a 1

PL/SQL procedure successfully completed
范佩西_11 2008-12-29
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 sleepzzzzz 的回复:]
TO:mantisXF(枫の叶)
哈哈,反正你没申请版权,被我学习了.
[/Quote]哈哈,学以致用啊。我也学习一下,下次教人
sleepzzzzz 2008-12-29
  • 打赏
  • 举报
回复
TO:mantisXF(枫の叶)
哈哈,反正你没申请版权,被我学习了.
mantisXF 2008-12-29
  • 打赏
  • 举报
回复
哈哈,学习了![Quote=引用 3 楼 sleepzzzzz 的回复:]
引用楼主 xlongbuilder 的帖子:
不过该函数貌似不能解决下面的问题
如表 A 中a字段存了总金额99,userid 字段中存了aa,22,bb 这样的用户id数据,我要把金额平均分配给每个人
A
id userid je
-------
1 aa,22,bb 99
2 dd2,3a 2
........
我如何才能将该数据变成
id userid je
1 aa 33
1 22 33
1 bb 33
2 dd2 1
2 3a 1



SQL code/*
SQL> drop table a;

Table dropped

SQL> creat…
[/Quote]
dinghaohong81 2008-12-29
  • 打赏
  • 举报
回复
楼主问题我没有看懂
hyee 2008-12-29
  • 打赏
  • 举报
回复
3楼的思路确实巧妙
yangyong29 2008-12-29
  • 打赏
  • 举报
回复
学习了,呵呵
xlongbuilder 2008-12-26
  • 打赏
  • 举报
回复
是啊
强悍的一塌糊涂 呵呵
谢谢各位
heipingoo8 2008-12-25
  • 打赏
  • 举报
回复
太牛了
学习ing
jdsnhan 2008-12-25
  • 打赏
  • 举报
回复
3楼的玩这个是强项。
sjq521521 2008-12-25
  • 打赏
  • 举报
回复
学习了。
sleepzzzzz 2008-12-25
  • 打赏
  • 举报
回复
[Quote=引用楼主 xlongbuilder 的帖子:]
不过该函数貌似不能解决下面的问题
如表 A 中a字段存了总金额99,userid 字段中存了aa,22,bb 这样的用户id数据,我要把金额平均分配给每个人
A
id userid je
-------
1 aa,22,bb 99
2 dd2,3a 2
........
我如何才能将该数据变成
id userid je
1 aa 33
1 22 33
1 bb 33
2 dd2 1
2 3a 1
[/Quote]

/*
SQL> drop table a;

Table dropped

SQL> create table A (id int,userid varchar2(20), je int);

Table created

SQL> insert into A values(1,'aa,22,bb',99);

1 row inserted

SQL> insert into A values(2,'dd2,3a',2);

1 row inserted

SQL> commit;

Commit complete */

SQL> select * from A;

ID USERID JE
------------ --------------- ----------
1 aa,22,bb 99
2 dd2,3a 2

SQL> select id,userid,je/(count(1) over(partition by id)) as je
2 from (
3 select id,substr(',' || userid || ',',
4 instr(',' || userid || ',', ',', 1, rn) + 1,
5 instr(',' || userid || ',', ',', 1, rn + 1) -
6 instr(',' || userid || ',', ',', 1, rn) - 1) as userid,
7 je
8 from A,
9 (select rownum rn
10 from all_objects
11 where rownum <= (select max(length(userid) -
12 length(replace(userid, ',')) + 1)
13 from A)))
14 where userid is not null
15 /

ID USERID JE
-------------- ------------ ----------
1 aa 33
1 22 33
1 bb 33
2 dd2 1
2 3a 1

SQL>


范佩西_11 2008-12-25
  • 打赏
  • 举报
回复
直接用sql很难搞,给你写了个procedure,直接输出结果:
create or replace procedure pro_split as
cu sys_refcursor;
arow a%rowtype;
v_userid varchar2(20);

n number;
v_user_idout varchar2(20);
begin
open cu for
select * from a;
loop
fetch cu
into arow;
exit when cu%notfound;
n := 1;
v_userid := arow.userid;
while instr(v_userid, ',') > 0 loop

v_userid := substr(v_userid, instr(v_userid, ',') + 1);
n := n + 1;
end loop;
v_userid := arow.userid;
while instr(v_userid, ',') > 0 loop

v_user_idout := substr(v_userid, 1, instr(v_userid, ',') - 1);
v_userid := substr(v_userid, instr(v_userid, ',') + 1);
dbms_output.put_line(arow.id || ' ' || v_user_idout || ' ' ||
(arow.je / n));
end loop;
dbms_output.put_line(arow.id || ' ' || v_userid || ' ' ||
(arow.je / n));
end loop;
end;

SQL> exec pro_split;

1 aa 33
1 22 33
1 bb 33
2 dd2 1
2 3a 1

PL/SQL procedure successfully completed
又是违规昵称 2008-12-25
  • 打赏
  • 举报
回复
这个仅仅用sql好像不是很好搞,
就是针对一条记录拆开也要做一个插入一个删除共两个操作吧

17,086

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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