使用MySQL存储过程创建动态交叉表(3)

使用 MySQL 存储过程创建动态交叉表

 

 

今天几乎看了一天关于 SQL 生成 Crosstab 的话题。从网上找了很多例子,也学到一些东西,现在简单总结:

 

我的有一个 demand 表:

 

DROP TABLE IF EXISTS `xcvrs`.`demand`;

CREATE TABLE  `xcvrs`.`demand` (

  `item_code` varchar(15) NOT NULL,      /* 产品代码 */

  `week_code` varchar(20) NOT NULL,     /* 周代码 */

  `dmd_qty` int(10) unsigned NOT NULL   /* 所需数量 */

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

我想生成一个 Crosstab ,纵轴是 item_code ,横轴是 week_code ,体是 dmd_qty 的和。网上给出了两种方法:

l            直接用 SQL 语句实现,通常用于横轴列固定情况;

l            使用存储过程,通常可用于横轴列不固定情况。

 

1.       直接用 SQL 语句实现

很简单,基本用到的就是 case 语句:

SELECT `item_code`,

SUM(CASE week_code WHEN 'Feb-Wk01' THEN dmd_qty ELSE 0 END) as `Feb-Wk01`,

SUM(CASE week_code WHEN 'Feb-Wk02' THEN dmd_qty ELSE 0 END) as `Feb-Wk02`,

SUM(CASE week_code WHEN 'Feb-Wk03' THEN dmd_qty ELSE 0 END) as `Feb-Wk03`,

SUM(CASE week_code WHEN 'Feb-Wk04' THEN dmd_qty ELSE 0 END) as `Feb-Wk04`

FROM `demand` GROUP BY `item_code`

 

 

2.       使用存储过程

我查了 N 多中文文章,几乎一窝蜂全都是 SQL Server 的例子。 MySQL 的例子少之又少,而且没找到能够顺利运行的。我本来对存储过程就不太熟,这下更加头昏脑胀。

无奈晚上 google ,间接搜到两篇文章,我已经转贴在我的 blog 里了:

l            The Wizard revisited: Dynamic Crosstabs using MySQL Stored Procedures

l            A mail from the Wizard himself

 

看了这两篇文章,摸到了一些头绪。将上面的 CASE 语句利用循环生成动态 SQL ,再执行获得查询结果。

 

DELIMITER $$

 

DROP PROCEDURE IF EXISTS `xcvrs`.`xtab02` $$

CREATE PROCEDURE `xcvrs`.`xtab02` ()

BEGIN

 

    DECLARE `xtab_query`      VARCHAR(4096)  DEFAULT '';

    DECLARE `done`           INT            DEFAULT 0;

    DECLARE `temp_week`      VARCHAR(10);

 

    DECLARE `column_cursor` CURSOR FOR

        SELECT DISTINCT `week_code` FROM `demand` ORDER BY `week_code`;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET `done` = 1;

 

 

    /* Create the CASE phrase via loop */

    OPEN `column_cursor`;

    column_loop: LOOP

        FETCH `column_cursor` INTO `temp_week`;

        IF `done` THEN LEAVE column_loop; END IF;

        SET `xtab_query` = CONCAT(`xtab_query`,

                                  ', SUM(CASE `week_code` WHEN /'',

                                  temp_week,

                                  '/' THEN dmd_qty ELSE 0 END) AS `',

                                  temp_week,

                                   '`');

    END LOOP column_loop;

    CLOSE `column_cursor`;

 

 

    /* Connect the SQL parts */

    SET `xtab_query` = CONCAT('SELECT `item_code`',

                            `xtab_query`, ' FROM demand GROUP BY `item_code`');

 

    /* Execute crosstab */

    SET @xtab_query = `xtab_query`;

    PREPARE `xtab02` FROM @xtab_query;

    EXECUTE `xtab02`;

    DEALLOCATE PREPARE `xtab02`;

 

 

END $$

 

DELIMITER ;

 

然后执行 call xtab02() ,即得到所需结果。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值