Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4184109
  • 博文数量: 240
  • 博客积分: 11504
  • 博客等级: 上将
  • 技术积分: 4277
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-28 14:24
文章分类

全部博文(240)

分类: Mysql/postgreSQL

2008-07-02 10:38:53

好像ORACLE中有相应的函数,可惜在MSSQL 或者MySQL中没有对应的函数。后两者就得用临时表来实现了。

1、表结构以及示例数据。

create table company
(dep char(10) not null,
val1 int unsigned not null
);
insert into company values
(
'市场部', 26),
('市场部',25),
('市场部',24),
('办公室',16),
('办公室',12),
('研发部',19),
('研发部'
,11);

2、存储过程

1)、循环实现

DELIMITER $$

CREATE DEFINER=`root`@`%` PROCEDURE `sp_generate_auto`()
BEGIN
declare cnt int default 0;
declare i int default 0;
drop table if exists tmp;
-- Temporary table to save the result.
create temporary table tmp like company;
alter table tmp add num int unsigned not null;
select count(1) as total from (select count(1) from company where 1 group by dep) T into cnt;
while i < cnt
do
set @stmt = concat('select dep from company where 1 group by dep order by dep asc limit ',i,',1 into @t_dep');
prepare s1 from @stmt;
execute s1;
deallocate prepare s1;
set @stmt = NULL;
set @num = 0;
set @stmt2 = concat('insert into tmp select dep,val1,@num := @num + 1 as sequence from company where dep = ''',@t_dep,''' order by dep asc');
prepare s1 from @stmt2;
execute s1;
deallocate prepare s1;
set @stmt2 = NULL;
set i = i + 1;
end while;
select * from tmp;
set @t_dep = NULL;
END$$

DELIMITER ;

2)、游标实现

DELIMITER $$



DROP PROCEDURE IF EXISTS `sp_generate_auto_cursor`$$



CREATE DEFINER=`root`@`%` PROCEDURE `sp_generate_auto_cursor`()

BEGIN

  declare done1 int default 0;

  declare a char(10);

  declare i int unsigned default 0;
-- Cursor one to get the group total
  declare cur1 cursor for select dep from company group by dep;

  declare continue handler for 1329 set done1 = 1;

-- Temporary table to save the result.

  drop table if exists tmp;

  create table tmp like company;

  alter table tmp add num int unsigned not null;

  open cur1;

  while done1 != 1

  do

    fetch cur1 into a;

    if not done1 then

      set @i = 0;

      begin

      declare done2 int default 0;

      declare b int unsigned default 0;

      declare c int unsigned default 0;
-- Cursor two to get per group total.
      declare cur2 cursor for select val1,@i := @i + 1 from company where dep = a;

      declare continue handler for 1329 set done2 = 1;

        open cur2;

        while done2 <> 1

        do

          fetch cur2 into b,c;

          if not done2 then

            insert into tmp select a,b,c;

          end if;

        end while;

        close cur2;

      end;

    end if;

  end while;

  close cur1;

  select * from tmp;

END$$



DELIMITER ;



3、调用结果

call sp_generate_auto();
call sp_generate_auto_cursor();

query result(7 records)

depval1num
办公室 16 1
办公室 12 2
市场部 26 1
市场部 25 2
市场部 24 3
研发部 19 1
研发部 11 2

uery result(7 records)

depval1num
办公室 16 1
办公室 12 2
市场部 26 1
市场部 25 2
市场部 24 3
研发部 19 1
研发部 11 2
(7 row(s)returned)
(15 ms taken)

(0 row(s)affected)
(0 ms taken)

(7 row(s)returned)
(16 ms taken)

(0 row(s)affected)
(0 ms taken)





阅读(6377) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-12-08 19:18:46

好歹给点注释啦~

fredyj2008-08-19 11:04:08

似乎不用临时表 set @num = 0; set @dep = ''; select *, @num := if(@dep = dep, @num + 1, 1) as row_number, @dep := dep as dummy from company order by dep; ZT: http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/