一个比较复杂的查询的实现

今天刚刚在SQL版问的,原帖见http://community.csdn.net/Expert/topic/5207/5207097.xml?temp=.4154932 。这里总结一下。

需求描述:

向各个考点寄考卷,要打印信封上的标签,包括考点代码、考点名称、地址什么的。

比如考点A,要寄805份考卷,由于不可能把所有805份考卷都装到一个信封里,所以打算每个信封装8份,一共装101份。

通过考生表可以得到每个考点各自有多少考生。

查询的结果形式如下:

考点信息(代码、名称、地址等),试卷份数

那么对于上面所举的例子,如何得到:

A(考点各信息),8
A(考点各信息),8
A(考点各信息),8
……
A(考点各信息),8
A(考点各信息),5

(以上结果为101条记录)

不知道我说清楚没

另外,每个信封里面所装的考卷份数,最好也能够灵活变动,比如下次要改成每个里面装5份了。我想上面的功能实现了,这个改成传参数就行了。

初步想法:通过循环,组合出union all的查询,记录在@sql varchar(8000)变量中,但是由于这个有长度限制,太长了就不行了

coolingpipe(冷箫轻笛) 的方法:

--环境
create table tab
(
code int,
name varchar(10)
)

insert into tab select 1,'第一考点'

create table tnum
(
num int
)

declare @i int
set @i = 0
while (@i <= 1000)
begin
insert into tnum select @i
set @i = @i + 1
end

--语句
declare @int int
declare @all int
set @int = 8
set @all = 85

select t1.*,case when @all - t2.num * @int >= 8 then 8 else @all - t2.num * @int end as [试卷份数]
from tab t1 inner join tnum t2 on t2.num * @int <= @all

--结果
code        name       试卷份数       
----------- ---------- -----------
1           第一考点       8
1           第一考点       8
1           第一考点       8
1           第一考点       8
1           第一考点       8
1           第一考点       8
1           第一考点       8
1           第一考点       8
1           第一考点       8
1           第一考点       8
1           第一考点       5

(所影响的行数为 11 行)

--删除环境
drop table tab
drop table tnum

dawugui(潇洒老乌龟) 的方法:

if object_id('pubs..tb') is not null
   drop table tb
go

create table tb
(
name varchar(20),
cnt  int
)

declare @count as int  --总数
set @count = 805
declare @per   as int  --每信封的数量
set @per = 200
declare @i as int --循环变量
set @i = 1
declare @j as int --信封总数
if @count % @per = 0
   begin
     set @j = @count / @per
     while @i <= @j
       begin
         insert into tb(name,cnt) values('A的信息' , @per)
         set @i = @i + 1
       end
   end
else
   begin
     set @j = @count / @per
     while @i <= @j
       begin
         insert into tb(name,cnt) values('A的信息' , @per)
         set @i = @i + 1
       end
       insert into tb(name,cnt) values('A的信息' , @count % @per)
   end


select * from tb
drop table tb

name                 cnt        
-------------------- -----------
A的信息                 200
A的信息                 200
A的信息                 200
A的信息                 200
A的信息                 5

(所影响的行数为 5 行)

我最终的解决方案(整个存储过程中的相关部分):

搞定了,写成了存储过程,其中相关部分如下。sbk为考生库,从中可以计算出每个考点的人数。用了辅助表kdbuffer,两个字段:bmddm(报名点代码)和cnt。然后用视图与这个表查询得到最终结果。@per为每个信封的试卷份数,是存储过程的输入参数。@i相当于冷箫轻笛的那个辅助表中的值。

declare @i int
declare @bmddm char(4)
declare @total int

delete from kdbuffer

declare c cursor for select bmddm, count(bmddm) t from sbk group by bmddm
open c
fetch next from c into @bmddm,@total
while @@fetch_status=0
begin
set @i=0
while @i * @per <= @total
begin
insert into kdbuffer
select @bmddm,case when @total - @i * @per >= @per then @per else @total - @i * @per end

set @i=@i+1
end

fetch next from c into @bmddm,@total
end
close c
deallocate c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值