ITPub博客

首页 > 数据库 > Oracle > 行转列的一种优化思路

行转列的一种优化思路

Oracle 作者:壹頁書 时间:2014-05-14 11:11:44 1 删除 编辑
在论坛看到一个帖子,需求是行转列。
但是表中的数据是千万级别的,运行很慢。

楼主的SQL
  1. set linesize 300;
  2. set pagesize 300;
  3. WITH t AS
  4. (
  5.  SELECT 'shop001' AS shopcode, 'store002' storecode,101 b_ID, 2 num,10.5 price FROM dual
  6.  UNION ALL
  7.  SELECT 'shop001' AS shopcode, 'store003' storecode,101 b_ID, 12 num,8 price FROM dual
  8.  UNION ALL
  9.  SELECT 'shop002' AS shopcode, 'store002' storecode,105 b_ID, 8 num,12.5 price FROM dual
  10.  UNION ALL
  11.  SELECT 'shop001' AS shopcode, 'store003' storecode,101 b_ID, 20 num,19 price FROM dual
  12.  UNION ALL
  13.  SELECT 'shop001' AS shopcode, 'store002' storecode,101 b_ID, 22 num,7 price FROM dual
  14.  UNION ALL
  15.  SELECT 'shop002' AS shopcode, 'store003' storecode,105 b_ID, 7 num,6 price FROM dual
  16.  UNION ALL
  17.  SELECT 'shop001' AS shopcode, 'store003' storecode,101 b_ID, 10 num,3 price FROM dual
  18.  UNION ALL
  19.  SELECT 'shop001' AS shopcode, 'store002' storecode,106 b_ID, 15 num,8 price FROM dual
  20.  )
  21. select shopcode,storecode,
  22.        sum(case when b_id=101 then num end) a,
  23.        sum(case when b_id=105 then num end) b,
  24.        sum(case when b_id=106 then num end) c,
  25.        sum(case when b_id=101 then num*price end) ,
  26.        sum(case when b_id=105 then num*price end) d,
  27.        sum(case when b_id=106 then num*price end) e
  28.        from t
  29.        GROUP BY shopcode,storecode;
  30. exit;

newkid大神优化的SQL
  1. set linesize 300;
  2. set pagesize 300;
  3. WITH t AS
  4. (
  5.  SELECT 'shop001' AS shopcode, 'store002' storecode,101 b_ID, 2 num,10.5 price FROM dual
  6.  UNION ALL
  7.  SELECT 'shop001' AS shopcode, 'store003' storecode,101 b_ID, 12 num,8 price FROM dual
  8.  UNION ALL
  9.  SELECT 'shop002' AS shopcode, 'store002' storecode,105 b_ID, 8 num,12.5 price FROM dual
  10.  UNION ALL
  11.  SELECT 'shop001' AS shopcode, 'store003' storecode,101 b_ID, 20 num,19 price FROM dual
  12.  UNION ALL
  13.  SELECT 'shop001' AS shopcode, 'store002' storecode,101 b_ID, 22 num,7 price FROM dual
  14.  UNION ALL
  15.  SELECT 'shop002' AS shopcode, 'store003' storecode,105 b_ID, 7 num,6 price FROM dual
  16.  UNION ALL
  17.  SELECT 'shop001' AS shopcode, 'store003' storecode,101 b_ID, 10 num,3 price FROM dual
  18.  UNION ALL
  19.  SELECT 'shop001' AS shopcode, 'store002' storecode,106 b_ID, 15 num,8 price FROM dual
  20.  )
  21. select shopcode,storecode,
  22.        sum(case when b_id=101 then s1 end) a,
  23.        sum(case when b_id=105 then s1 end) b,
  24.        sum(case when b_id=106 then s1 end) c,
  25.        sum(case when b_id=101 then s2 end) ,
  26.        sum(case when b_id=105 then s2 end) d,
  27.        sum(case when b_id=106 then s2 end) e
  28.        from(
  29.                        SELECT SHOPCODE, STORECODE, B_ID, SUM(num) S1, SUM(num * price) S2
  30.                        FROM t
  31.                        GROUP BY SHOPCODE, STORECODE, B_ID
  32.            )
  33.        GROUP BY SHOPCODE, STORECODE;
  34.        exit;


优化的思路就是
sum和表扫描省略不了,
但是可以通过两次分组,省下千万次的case when判断

参考:
http://www.itpub.net/thread-1781658-1-1.html

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29254281/viewspace-1160880/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: MySQL Join Buffer
下一篇: JAVA切分大文件
请登录后发表评论 登录
全部评论

注册时间:2013-10-19

  • 博文量
    620
  • 访问量
    6339968