特难的SQL,请高书帮助,急,跪求各位大峡!!!
我的表结构是这样的
itemcode 销售数量 次数 级别
00001 15 2
00002 15 2
00003 10 1
00004 10 2
00005 10 1
00006 8 2
00007 8 1
00008 7 1
00009 6 2
00010 5 2
00011 3 2
00012 1 1
00013 1 1
00014 1 1
我的要求是根据销售总数量进行汇总,然后根据销售数量的排序(desc)一条一条往下加,当达到销售总数量40%时,次数>1的级别为A1,等于1的级别为A2,然后重新从下条开始累加,达到销售总数量36%时, 次数>1的级别为B1,等于1的级别为B2,达到销售总数量18%时, 次数>1的级别为C1,等于1的级别为C2,达到销售总数量6%时, 次数>1的级别为D1,等于1的级别为D2,
具体结果为:
itemcode 销售数量 次数 级别
00001 15 2 A1
00002 15 2 A1
00003 10 1 A2
00004 10 2 B1
00005 10 1 B2
00006 8 2 B1
00007 8 1 B2
00008 7 1 C2
00009 6 2 C1
00010 5 2 C1
00011 3 2 D1
00012 1 1 D2
00013 1 1 D2
00014 1 1 D2
[解决办法]
使用Oracle的分析函数(over,dense)。
[解决办法]
这可行吗?
如果前面不是正好的40%,36%,比如41%,36%,18%,5%,那5%的部分将永远不可能被分类了
[解决办法]
这种需求用SQL能做,用程序写吧.
[解决办法]
这个要用存储过程去实现了
[解决办法]
直接使用分析函数肯定能做出来,但要累伤人的。
还上赞同使用存贮过程。
[解决办法]
-- 好象也不复杂啊,发现规律就好办SQL> select * from test;ITEMCODE SALS CS JB---------- ---------- ---------- ----00001 15 2 00002 15 2 00003 10 1 00004 10 2 00005 10 1 00006 8 2 00007 8 1 00008 7 1 00009 6 2 00010 5 2 00011 3 2 00012 1 1 00013 1 1 00014 1 1 14 rows selectedSQL> with x as (select itemcode,sals,cs,sum(sals) over() sals_total, 2 sum(sals) over(order by rownum)/sum(sals) over() sals_bfb 3 from test 4 order by sals desc,itemcode) 5 select itemcode,sals,cs, 6 case when sals_bfb<=0.4 and cs=1 then 'A2' 7 when sals_bfb>0.4 and sals_bfb<=(0.4+0.36) and cs=1 then 'B2' 8 when sals_bfb>(0.4+0.36) and sals_bfb<=(0.4+0.36+0.18) and cs=1 then 'C2' 9 when sals_bfb>(0.4+0.36+0.18) and sals_bfb<=(0.4+0.36+0.18+0.06) and cs=1 then 'D2' 10 else (case when sals_bfb <= 0.4 then 'A1' 11 when sals_bfb > 0.4 and sals_bfb <= (0.4+0.36) then 'B1' 12 when sals_bfb>(0.4+0.36) and sals_bfb<=(0.4+0.36+0.18) then 'C1' 13 when sals_bfb>(0.4+0.36+0.18) and sals_bfb<=(0.4+0.36+0.18+0.06) then 'D1' 14 else 'E0' 15 end) 16 end JB 17 from x 18 /ITEMCODE SALS CS JB---------- ---------- ---------- --00001 15 2 A100002 15 2 A100003 10 1 A200004 10 2 B100005 10 1 B200006 8 2 B100007 8 1 B200008 7 1 C200009 6 2 C100010 5 2 C100011 3 2 D100012 1 1 D200013 1 1 D200014 1 1 D214 rows selectedSQL>
[解决办法]
--楼主根据实际条件再修改一下:SQL> select * from t_1123;ITEMCODE ITEMSUM ITEMCOUNT FLAG-------- ------- --------- ----00001 15 2 00002 15 2 00003 10 1 00004 10 2 00005 10 1 00006 8 2 00007 8 1 00008 7 1 00009 6 2 00010 5 2 00011 3 2 00012 1 1 00013 1 1 00014 1 1 14 rows selectedSQL> SQL> create or replace procedure p_item_order as 2 itemcode t_1123.itemcode%type; 3 itemsum t_1123.itemsum%type; 4 itemcount t_1123.itemcount%type; 5 flag t_1123.flag%type; 6 7 cursor c1 is 8 select count(*) from t_1123; 9 10 cursor c2 is 11 select itemcode, itemsum, itemcount 12 from t_1123 13 where itemcode = (select min(itemcode) 14 from t_1123 15 where flag is null 16 or flag = ''); 17 18 cursor c3 is 19 select sum(itemsum) from t_1123 where flag is not null; 20 21 v_t1123 number(4) := 0; 22 v_sum number(3) := 0; 23 v_count number(3) := 0; 24 v_itemsum number(3) := 0; 25 v_itemcode varchar2(5); 26 27 begin 28 open c1; 29 fetch c1 30 into v_t1123; 31 for i in 1 .. 3 loop 32 open c2; 33 fetch c2 34 into v_itemcode, v_sum, v_count; 35 open c3; 36 fetch c3 37 into v_itemsum; 38 if v_itemsum is null then 39 update t_1123 set flag = 'A1' where itemcode = v_itemcode; 40 end if; 41 if v_itemsum is not null then 42 update t_1123 43 set flag = 'A1' 44 where v_sum / v_itemsum >= 0.4 45 and v_count > 1 46 and itemcode = v_itemcode; 47 end if; 48 update t_1123 49 set flag = 'A2' 50 where v_sum / v_itemsum >= 0.2 51 and v_count = 1 52 and itemcode = v_itemcode; 53 commit; 54 close c2; 55 close c3; 56 end loop; 57 for i in 4 .. v_t1123 loop 58 open c2; 59 fetch c2 60 into v_itemcode, v_sum, v_count; 61 open c3; 62 fetch c3 63 into v_itemsum; 64 update t_1123 65 set flag = 'B1' 66 where v_sum / v_itemsum >= 0.36 67 and v_sum / v_itemsum < 0.4 68 and v_count > 1 69 and itemcode = v_itemcode; 70 update t_1123 71 set flag = 'B2' 72 where v_sum / v_itemsum >= 0.36 73 and v_sum / v_itemsum < 0.4 74 and v_count = 1 75 and itemcode = v_itemcode; 76 update t_1123 77 set flag = 'C1' 78 where v_sum / v_itemsum >= 0.18 79 and v_sum / v_itemsum < 0.36 80 and v_count > 1 81 and itemcode = v_itemcode; 82 update t_1123 83 set flag = 'C2' 84 where v_sum / v_itemsum >= 0.18 85 and v_sum / v_itemsum < 0.36 86 and v_count = 1 87 and itemcode = v_itemcode; 88 update t_1123 89 set flag = 'D1' 90 where v_sum / v_itemsum >= 0.06 91 and v_sum / v_itemsum < 0.18 92 and v_count > 1 93 and itemcode = v_itemcode; 94 update t_1123 95 set flag = 'D2' 96 where v_sum / v_itemsum >= 0.06 97 and v_sum / v_itemsum < 0.18 98 and v_count = 1 99 and itemcode = v_itemcode;100 101 commit;102 103 close c2;104 close c3;105 end loop;106 close c1;107 end;108 /Procedure createdSQL> exec p_item_order;PL/SQL procedure successfully completedSQL> select * from t_1123;ITEMCODE ITEMSUM ITEMCOUNT FLAG-------- ------- --------- ----00001 15 2 A100002 15 2 A100003 10 1 A200004 10 2 C100005 10 1 C200006 8 2 D100007 8 1 D200008 7 1 D200009 6 2 D100010 5 2 00011 3 2 00012 1 1 00013 1 1 00014 1 1 14 rows selectedSQL>
[解决办法]
可能今天俺脑子不好使了,总共才100的数量,15也只占总数量的15%,为什么第一条记录是A1?呵呵...
当达到销售总数量40%时,次数>1的级别为A1,等于1的级别为A2
--- 更新表,将上面代码套上就行了啊.SQL> update test t1 2 set 3 jb = (select jb 4 from ( 5 with x as (select itemcode,sals,cs,sum(sals) over() sals_total, 6 sum(sals) over(order by rownum)/sum(sals) over() sals_bfb 7 from test 8 order by sals desc,itemcode) 9 select itemcode,sals,cs, 10 case when sals_bfb<=0.4 and cs=1 then 'A2' 11 when sals_bfb>0.4 and sals_bfb<=(0.4+0.36) and cs=1 then 'B2' 12 when sals_bfb>(0.4+0.36) and sals_bfb<=(0.4+0.36+0.18) and cs=1 then 'C2' 13 when sals_bfb>(0.4+0.36+0.18) and sals_bfb<=(0.4+0.36+0.18+0.06) and cs=1 then 'D2' 14 else (case when sals_bfb <= 0.4 then 'A1' 15 when sals_bfb > 0.4 and sals_bfb <= (0.4+0.36) then 'B1' 16 when sals_bfb>(0.4+0.36) and sals_bfb<=(0.4+0.36+0.18) then 'C1' 17 when sals_bfb>(0.4+0.36+0.18) and sals_bfb<=(0.4+0.36+0.18+0.06) then 'D1' 18 else 'E0' 19 end) 20 end JB 21 from x)t where t.itemcode = t1.itemcode) 22 /14 rows updatedSQL>
[解决办法]