Oracle语句求教,急..........................................

小飛不想飛 2013-09-25 11:09:49
例如:
tab1(销售订单表):
编号 客户 业务员 商品 单价 数量 时间
SO001 1号店 小明 苹果4 3000 200 2013-07-05
SO002 2号店 小明 苹果5 4200 100 2013-08-05
SO003 1号店 小明 苹果4S 3500 300 2013-07-13
SO004 3号店 小明 苹果4 3000 350 2013-08-09
SO005 2号店 小明 苹果5 4100 600 2013-08-18
SO006 4号店 小明 苹果5S 4500 150 2013-09-07
SO001 3号店 小明 苹果4 3100 100 2013-08-23
SO001 4号店 小明 苹果4S 3600 700 2013-09-16
SO001 1号店 小明 苹果4 3200 400 2013-07-22


希望统计得到苹果4的销售数量:
商品 客户 7月数量 8月数量 9月数量
苹果4 1号店 600 0 0
苹果4 3号店 0 450 0

PS:现在有2个参数日期,一个开始日期和结束日期,根据日期来决定查询的月份。
如参数开始日期:2013-05-16,结束日期:2013-09-17
那么我查询到的月份字段就有5月数量、6月数量、7月数量、8月数量、9月数量,而5月份的数据必须是5月16号之后的,同样,9月统计的数量必须是9月17号之前的。

求语句,我现在的做法是根据2个日期得到月份,然后循环月份,把月份放进SQL语句执行,每个月每个月的查,如果我2个日期区间有10个月,那么我一条数据就要访问10次数据库,导致查询效率大大降低。查询到的数据还没100条,却要花上将近1分钟的时间。像这种直接统计的不会啊,求大神
...全文
123 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
测试 传2个时间 返回的sql查询 得到下面数据

P_TEST(2013/5/5,2013/8/12)


     KH     SP    05    06    07    08
------------------------------------------------------------
1	1号店	苹果4	0	330	200	0
2	1号店	苹果4s	0	0	300	0
3	2号店	苹果4s	440	0	0	0
4	2号店	苹果5	0	0	0	100
5	3号店	苹果4	0	0	0	250
6	3号店	苹果5	0	0	0	350

  • 打赏
  • 举报
回复
test 试试看可以么

CREATE OR REPLACE PROCEDURE P_TEST (B_DATE IN DATE,E_DATE IN DATE)
IS
  V_SQL VARCHAR2(2000);
  CURSOR CURSOR_1 IS 
  SELECT DISTINCT TO_CHAR(T.SJ,'MM') SJ 
  FROM tab1 T
  WHERE T.SJ BETWEEN B_DATE AND E_DATE
  ORDER BY TO_CHAR(T.SJ,'MM'); 
    
    BEGIN
      V_SQL := 'SELECT KH,SP ';
      FOR V_TB IN CURSOR_1
      LOOP
        V_SQL := V_SQL || ',' || 'SUM(DECODE(TO_CHAR(T.SJ,''MM''),''' 
              || V_TB.SJ || ''',SL,0)) AS "'|| V_TB.SJ ||'"';
      END LOOP;
      V_SQL := V_SQL || ' FROM TAB1 T' ;
      V_SQL := V_SQL || ' WHERE T.SJ BETWEEN '||B_DATE|| ' AND '||E_DATE;
      V_SQL := V_SQL || ' GROUP BY KH,SP ORDER BY KH,SP';
     DBMS_OUTPUT.PUT_LINE(V_SQL);
    --EXECUTE IMMEDIATE V_SQL;
    END;
请叫我-雷人 2013-09-25
  • 打赏
  • 举报
回复
占个座,看神兽表演。
小飛不想飛 2013-09-25
  • 打赏
  • 举报
回复
引用 3 楼 HJ_daxian 的回复:
构造了点基础数据 吃饭来弄 10分钟的事

create table tab1 (kh nvarchar2(20),sp nvarchar2(20),sl number(6),sj date);

insert into tab1 
select '1号店','苹果4',200,date'2013-07-05' from dual union all
select '2号店','苹果5',100,date'2013-08-05' from dual union all
select '1号店','苹果4s',300,date'2013-07-13' from dual union all
select '3号店','苹果5',350,date'2013-08-08' from dual union all
select '2号店','苹果5s',600,date'2013-08-15' from dual union all
select '4号店','苹果4',150,date'2013-09-05' from dual union all
select '1号店','苹果4',330,date'2013-06-05' from dual union all
select '2号店','苹果4s',440,date'2013-05-15' from dual union all
select '3号店','苹果4',250,date'2013-08-11' from dual 
commit;

drop table tab1;
额,谢谢神兽
  • 打赏
  • 举报
回复
构造了点基础数据 吃饭来弄 10分钟的事

create table tab1 (kh nvarchar2(20),sp nvarchar2(20),sl number(6),sj date);

insert into tab1 
select '1号店','苹果4',200,date'2013-07-05' from dual union all
select '2号店','苹果5',100,date'2013-08-05' from dual union all
select '1号店','苹果4s',300,date'2013-07-13' from dual union all
select '3号店','苹果5',350,date'2013-08-08' from dual union all
select '2号店','苹果5s',600,date'2013-08-15' from dual union all
select '4号店','苹果4',150,date'2013-09-05' from dual union all
select '1号店','苹果4',330,date'2013-06-05' from dual union all
select '2号店','苹果4s',440,date'2013-05-15' from dual union all
select '3号店','苹果4',250,date'2013-08-11' from dual 
commit;

drop table tab1;
小飛不想飛 2013-09-25
  • 打赏
  • 举报
回复
引用 1 楼 HJ_daxian 的回复:
要用到动态sql了 下午有时间再弄
正准备把连接私信发给你的,速度帮我搞定啊,急用,搞出来的报表都被客户骂了,一点数据导出来要半天
  • 打赏
  • 举报
回复
要用到动态sql了 下午有时间再弄
  • 打赏
  • 举报
回复
一样可以实现 动态sql的效果
  • 打赏
  • 举报
回复
大概酱紫: 先计算出2个月份直接的月份 比如05 06 07 放到集合里面 string sql = "SELECT KH,SP"; for(int i = 0; i< 集合.length;i++) { sql += ",SUM(DECODE(TO_CHAR(T.SJ,'MM'),'"+集合(i)+"',SL,0) "; } sql += " where .. group by ...";
  • 打赏
  • 举报
回复
引用 9 楼 xp447196763 的回复:
你们的处理方法差不多,刚刚代码修改了,测试OK,原先查询2个月的数据大概有七八十条的样子,要12秒左右,现在只要6秒的样子(因为查询的内容过多,而且查出来的数据不是直接绑定,而是要在页面画HTML,数据显示要这么久),原先查询3个月的数据700条的样子,不知道要多久,现在也要30秒。我没有用到存储过程,直接页面写的SQL语句,虽然感觉还是有点慢,但现在也没时间继续优化了
你要是早说在页面上做 更简单了呀 上面的基础语句一样 把循环替换成代码里面的循环语句
小飛不想飛 2013-09-25
  • 打赏
  • 举报
回复
引用 7 楼 HJ_daxian 的回复:
测试 传2个时间 返回的sql查询 得到下面数据

P_TEST(2013/5/5,2013/8/12)


     KH     SP    05    06    07    08
------------------------------------------------------------
1	1号店	苹果4	0	330	200	0
2	1号店	苹果4s	0	0	300	0
3	2号店	苹果4s	440	0	0	0
4	2号店	苹果5	0	0	0	100
5	3号店	苹果4	0	0	0	250
6	3号店	苹果5	0	0	0	350

引用 8 楼 lyliu602 的回复:
你可以在程序中根据你的查询条件构造如下sql: SUM(DECODE(R.MONTH2,'2013-05',A.数量,0)) "5月数量", SUM(DECODE(R.MONTH2,'2013-06',A.数量,0)) "6月数量", SUM(DECODE(R.MONTH2,'2013-07',A.数量,0)) "7月数量", SUM(DECODE(R.MONTH2,'2013-08',A.数量,0)) "8月数量", SUM(DECODE(R.MONTH2,'2013-09',A.数量,0)) "9月数量" 只需要替换上面的这些,其余的可以参考下面的这段:

SELECT A.商品,A.客户,
SUM(DECODE(R.MONTH2,'2013-05',A.数量,0)) "5月数量",
SUM(DECODE(R.MONTH2,'2013-06',A.数量,0)) "6月数量",
SUM(DECODE(R.MONTH2,'2013-07',A.数量,0)) "7月数量",
SUM(DECODE(R.MONTH2,'2013-08',A.数量,0)) "8月数量",
SUM(DECODE(R.MONTH2,'2013-09',A.数量,0)) "9月数量"
FROM(
SELECT T.商品,T.客户,T.数量, SUBSTR(T.时间,1,7)MONTH2
FROM TAB1 T WHERE T.商品='苹果4'
AND T.时间>= '2013-05-16' AND T.时间<='2013-09-17'
GROUP BY T.商品,T.客户,T.数量,SUBSTR(T.时间,1,7) 
)A
RIGHT JOIN
(
SELECT TO_CHAR(ADD_MONTHS(TO_DATE(
       SUBSTR('2013-05-16',1,7), 'YYYY-MM'), ROWNUM - 1),
       'YYYY-MM') AS MONTH2 FROM DUAL
CONNECT BY ROWNUM <= (SELECT MONTHS_BETWEEN(TO_DATE(
        SUBSTR('2013-09-17',1,7), 'YYYY-MM'),
        TO_DATE(SUBSTR('2013-05-16',1,7), 'YYYY-MM'))FROM DUAL)+1
)R ON A.MONTH2 = R.MONTH2
WHERE A.商品||A.客户 IS NOT NULL
GROUP BY A.商品,A.客户;

商品   客户  5月数量   6月数量   7月数量  8月数量  9月数量
--------- --------------- ---------- ---------- ---------- ----------
苹果4  3号店   0         0        0        450      0
苹果4  1号店   0         0        600      0        0


表结构:
Name Type         Nullable Default Comments 
---- ------------ -------- ------- -------- 
编号 VARCHAR2(50) Y                         
客户 VARCHAR2(50) Y                         
业务员 VARCHAR2(50) Y                         
商品 VARCHAR2(50) Y                         
单价 VARCHAR2(50) Y                         
数量 VARCHAR2(50) Y                         
时间 VARCHAR2(50) Y         

测试数据:
insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO001', '1号店', '小明', '苹果4', '3000', '200', '2013-07-05');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO002', '2号店', '小明', '苹果5', '4200', '100', '2013-08-05');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO003', '1号店', '小明', '苹果4s', '3500', '300', '2013-07-13');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO004', '3号店', '小明', '苹果4', '3000', '350', '2013-08-09');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO005', '2号店', '小明', '苹果5', '4100', '600', '2013-08-18');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO006', '4号店', '小明', '苹果5s', '4500', '150', '2013-09-07');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO001', '3号店', '小明', '苹果4', '3100', '100', '2013-08-23');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO001', '4号店', '小明', '苹果4s', '3600', '700', '2013-09-16');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO001', '1号店', '小明', '苹果4', '3200', '400', '2013-07-22');
你们的处理方法差不多,刚刚代码修改了,测试OK,原先查询2个月的数据大概有七八十条的样子,要12秒左右,现在只要6秒的样子(因为查询的内容过多,而且查出来的数据不是直接绑定,而是要在页面画HTML,数据显示要这么久),原先查询3个月的数据700条的样子,不知道要多久,现在也要30秒。我没有用到存储过程,直接页面写的SQL语句,虽然感觉还是有点慢,但现在也没时间继续优化了
无敌小二傻 2013-09-25
  • 打赏
  • 举报
回复
你可以在程序中根据你的查询条件构造如下sql: SUM(DECODE(R.MONTH2,'2013-05',A.数量,0)) "5月数量", SUM(DECODE(R.MONTH2,'2013-06',A.数量,0)) "6月数量", SUM(DECODE(R.MONTH2,'2013-07',A.数量,0)) "7月数量", SUM(DECODE(R.MONTH2,'2013-08',A.数量,0)) "8月数量", SUM(DECODE(R.MONTH2,'2013-09',A.数量,0)) "9月数量" 只需要替换上面的这些,其余的可以参考下面的这段:

SELECT A.商品,A.客户,
SUM(DECODE(R.MONTH2,'2013-05',A.数量,0)) "5月数量",
SUM(DECODE(R.MONTH2,'2013-06',A.数量,0)) "6月数量",
SUM(DECODE(R.MONTH2,'2013-07',A.数量,0)) "7月数量",
SUM(DECODE(R.MONTH2,'2013-08',A.数量,0)) "8月数量",
SUM(DECODE(R.MONTH2,'2013-09',A.数量,0)) "9月数量"
FROM(
SELECT T.商品,T.客户,T.数量, SUBSTR(T.时间,1,7)MONTH2
FROM TAB1 T WHERE T.商品='苹果4'
AND T.时间>= '2013-05-16' AND T.时间<='2013-09-17'
GROUP BY T.商品,T.客户,T.数量,SUBSTR(T.时间,1,7) 
)A
RIGHT JOIN
(
SELECT TO_CHAR(ADD_MONTHS(TO_DATE(
       SUBSTR('2013-05-16',1,7), 'YYYY-MM'), ROWNUM - 1),
       'YYYY-MM') AS MONTH2 FROM DUAL
CONNECT BY ROWNUM <= (SELECT MONTHS_BETWEEN(TO_DATE(
        SUBSTR('2013-09-17',1,7), 'YYYY-MM'),
        TO_DATE(SUBSTR('2013-05-16',1,7), 'YYYY-MM'))FROM DUAL)+1
)R ON A.MONTH2 = R.MONTH2
WHERE A.商品||A.客户 IS NOT NULL
GROUP BY A.商品,A.客户;

商品   客户  5月数量   6月数量   7月数量  8月数量  9月数量
--------- --------------- ---------- ---------- ---------- ----------
苹果4  3号店   0         0        0        450      0
苹果4  1号店   0         0        600      0        0


表结构:
Name Type         Nullable Default Comments 
---- ------------ -------- ------- -------- 
编号 VARCHAR2(50) Y                         
客户 VARCHAR2(50) Y                         
业务员 VARCHAR2(50) Y                         
商品 VARCHAR2(50) Y                         
单价 VARCHAR2(50) Y                         
数量 VARCHAR2(50) Y                         
时间 VARCHAR2(50) Y         

测试数据:
insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO001', '1号店', '小明', '苹果4', '3000', '200', '2013-07-05');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO002', '2号店', '小明', '苹果5', '4200', '100', '2013-08-05');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO003', '1号店', '小明', '苹果4s', '3500', '300', '2013-07-13');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO004', '3号店', '小明', '苹果4', '3000', '350', '2013-08-09');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO005', '2号店', '小明', '苹果5', '4100', '600', '2013-08-18');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO006', '4号店', '小明', '苹果5s', '4500', '150', '2013-09-07');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO001', '3号店', '小明', '苹果4', '3100', '100', '2013-08-23');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO001', '4号店', '小明', '苹果4s', '3600', '700', '2013-09-16');

insert into tab1 (编号, 客户, 业务员, 商品, 单价, 数量, 时间)
values ('SO001', '1号店', '小明', '苹果4', '3200', '400', '2013-07-22');

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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