现在的位置: 首页 > 综合 > 正文

给定一个值,求组合该值的组合集合

2013年09月08日 ⁄ 综合 ⁄ 共 3039字 ⁄ 字号 评论关闭

怎样随机取得相同项目名称的数据,条件是只要取得的项目名称数量之和等于某个数(2或者3))
表结构(表名称:item):

项目名称    数量  
 a            1    

 a            2
 
 a            3
 
 a            4
 
 a            5

...

说明如下:

我要从表item里面查询出项目名称='a' and sum(数量)=6 的数据
随便几条数据都可以,只要符合上面的条件都行
比如可以查询出的结果为:
前面三条数据(项目名称='a' and sum(数量)=6)
也可以是第一条和最后一条,
也可以是第二条和倒数第二条

用sql语句可以实现吗?
我都整疯了?

--方法一:

--创建测试环境
declare @t table
(项目名称 varchar(20),数量 int)
insert @t
select 'a',1 union all
select 'a',2 union all
select 'a',3 union all
select 'a',4 union all
select 'a',5

--方法一:查询
 select *  from @t a join @t b
on a.项目名称=b.项目名称 and a.数量<>b.数量
where a.项目名称='a' and a.数量+b.数量=6

--结果

项目名称                 数量          项目名称                 数量         
-------------------- ----------- -------------------- -----------
a                    5           a                    1
a                    4           a                    2
a                    2           a                    4
a                    1           a                    5

(所影响的行数为 4 行)

--方法二,

思路可能不够严禁,提供邹建的另一种解决方式:

--测试数据
create table tb(id varchar(10),length numeric(10,2))
insert tb select 1,200
union all select 2,410
union all select 3,300
union all select 4,310
union all select 5,100
union all select 6,500
union all select 7,480
union all select 8,600
go

--查询函数
create function fn_search(
@Num numeric(10,2),
@step numeric(10,2)
)
returns @r table (gid varchar(10),id varchar(10),length numeric(10,2))
as
begin
 declare @t table (gid int identity,id varchar(8000),id1 varchar(10),length numeric(10,2),level int)
 declare @l int

 select @step=@num+@step,@l=0

 insert @r select '',id,length from tb where length between @Num and @step
 
 insert @t select ','+id+',',id,length,@l from tb where length<@step
 while @@rowcount>0
 begin
  insert @r select distinct case when a.id=b.id then gid+'.' else gid end,a.id,a.length
  from tb a,(
   select gid=rtrim(gid)
    ,a.id,a.length,id1=b.id from tb a,@t b
   where b.level=@l
    and b.id1<a.id
    and a.length between @num-b.length and @step-b.length
  )b where a.id=b.id or charindex(','+a.id+',',b.id1)>0
  
  set @l=@l+1
  insert @t select b.id+a.id+',',a.id,a.length+b.length,@l
  from tb a,@t b
  where b.level=@l-1
   and b.id1<a.id
   and a.length<@step-b.length
 end
 
 --生成组号
 declare @id decimal,@gid varchar(10),@i varchar(10)
 set @gid=0
 update @r set @gid=case when @id=gid then @gid else @gid+1 end
  ,@i=case when right(gid,1)='.' then @i-1 else 0 end
  ,gid=case when @i=0 then @gid else @gid+@i end
  ,@id=gid
 where gid>''
lb_exit:
 return
end
go

--调用测试1
select * from dbo.fn_search(600,0)
go

--删除测试
drop table tb
drop function fn_search

/*--测试结果

gid id length
 8 600.00
1 5 100.00
1-1 6 500.00
2 1 200.00
2 3 300.00
2-1 5 100.00

(所影响的行数为 6 行)

--*/

--方法三:

create table #tmp(px int,value int)
insert into #tmp select 5,5
insert into #tmp select 4,12
insert into #tmp select 7,9
insert into #tmp select 1,3
insert into #tmp select 3,6
insert into #tmp select 6,23
insert into #tmp select 2,15

declare @px int,@value int,@sum int,@m int,@px1 int
set @sum=0
set @m=20

declare t_cursor cursor for select px,value from #tmp order by px

open t_cursor
fetch next from t_cursor into @px,@value

while @@fetch_status=0
begin
    if(@sum>@m)
        break
    set @sum=@sum+@value
    set @px1=@px
    fetch next from t_cursor into @px,@value
end
close t_cursor
deallocate t_cursor

select * from #tmp where px<@px1 order by px
/*
px          value      
----------- -----------
1           3
2           15
*/

drop table #tmp

抱歉!评论已关闭.