首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

按条件限量随机提取记录有关问题

2012-02-07 
按条件限量随机提取记录问题DECLARE@test1table(c1varchar(10),c2varchar(10))INSERTINTO@test1(c1,c2)SEL

按条件限量随机提取记录问题
DECLARE   @test1   table(c1   varchar(10),c2   varchar(10))
INSERT   INTO   @test1   (c1,c2)
                    SELECT   '1 ', 'a '
UNION   ALL   SELECT   '2 ', 'a '
UNION   ALL   SELECT   '3 ', 'a '
UNION   ALL   SELECT   '4 ', 'b '
UNION   ALL   SELECT   '5 ', 'b '
UNION   ALL   SELECT   '6 ', 'b '
UNION   ALL   SELECT   '7 ', 'b '
UNION   ALL   SELECT   '8 ', 'c '
UNION   ALL   SELECT   '9 ', 'c '
UNION   ALL   SELECT   '10 ', 'd '
UNION   ALL   SELECT   '11 ', 'd '
UNION   ALL   SELECT   '12 ', 'd '
UNION   ALL   SELECT   '13 ', 'e '
UNION   ALL   SELECT   '14 ', 'e '
UNION   ALL   SELECT   '15 ', 'e '

DECLARE   @test2   table   (c2   varchar(10),cnt   int)
INSERT   INTO   @test2   (c2,MaxCnt)
                    SELECT   'a ',2
UNION   ALL   SELECT   'c ',1
UNION   ALL   SELECT   'd ',1

问题是在@test1中随机提取N条记录,记录不重复。
所取记录的c2次数不大于@test2中c2所对应的MaxCnt。
@test2中没对应的c2表示没有数量限制。
请问有没有方法能用一条语句高效实现?

[解决办法]
取n条随机记录
select top n from @test1 order by newid()
[解决办法]
比如楼主的数据,N=10

create table #(id varchar(5))
insert into # select 3
union all select 3
union all select 8
union all select 8

drop table #count
create table #count(ctid varchar(5))
insert into #count select '+ '
union all select '- '
union all select '* '
union all select '/ '

select identity(int,1,1) id, '( '+aid+b.ctid+ '( '+bid+c.ctid+ '( '+cid+d.ctid+did+ '))) '[mula] into #wei
from
(select DISTINCT a.id [aid],b.id [bid],c.id [cid],d.id+ '.0 ' [did] from # a,# b,# c,# d
where len(REPLACE(a.id+b.id+c.id+d.id, '3 ', ' '))=3
and len(REPLACE(a.id+b.id+c.id+d.id, '8 ', ' '))=3
and len(REPLACE(a.id+b.id+c.id+d.id, '8 ', ' '))=2)a
,#count b,#count c,#count d

create table #show(id int identity(1,1),result dec(18,3))

declare @int int,@var varchar(50)
set @int=1
while @int <=(select max(id)from #wei)
begin
select @var=mula from #wei where id=@int
insert into #show exec( 'select '+@var)
if(@@ERROR=8134)
insert into #show select null
set @int=@int+1
end

select * from #wei a join #show b on b.id=a.id
where b.result=24

drop table #count
drop table #
drop table #wei
drop table #show


DECLARE @test1 table(c1 varchar(10),c2 varchar(10))
INSERT INTO @test1 (c1,c2)
SELECT '1 ', 'a '
UNION ALL SELECT '2 ', 'a '
UNION ALL SELECT '3 ', 'a '
UNION ALL SELECT '4 ', 'b '
UNION ALL SELECT '5 ', 'b '
UNION ALL SELECT '6 ', 'b '
UNION ALL SELECT '7 ', 'b '


UNION ALL SELECT '8 ', 'c '
UNION ALL SELECT '9 ', 'c '
UNION ALL SELECT '10 ', 'd '
UNION ALL SELECT '11 ', 'd '
UNION ALL SELECT '12 ', 'd '
UNION ALL SELECT '13 ', 'e '
UNION ALL SELECT '14 ', 'e '
UNION ALL SELECT '15 ', 'e '

DECLARE @test2 table (c2 varchar(10),cnt int)
INSERT INTO @test2 (c2,Cnt)
SELECT 'a ',2
UNION ALL SELECT 'c ',1
UNION ALL SELECT 'd ',1

declare @Result table (c1 varchar(10),c2 varchar(10))
insert @Result
select top 10 * from @test1 order by newid()

while exists (
select 1 from @test2 a,(select c2,count(*) as cnt from @Result group by c2) b
where a.c2=b.c2 and a.cnt <b.cnt
)
begin
set rowcount 1
delete c
from @test2 a,(select c2,count(*) as cnt from @Result group by c2) b,@Result c
where a.c2=b.c2 and a.cnt <b.cnt and c.c2=a.c2
set rowcount 0
insert @Result
select top 1 * from @test1 a where not exists (
select 1 from @Result
where c1=a.c1 and c2=a.c2
) order by newid()
end

select * from @Result

--第一次运行结果(运气好,没有删除)

(所影响的行数为 15 行)


(所影响的行数为 3 行)


(所影响的行数为 10 行)

c1 c2
---------- ----------
6 b
2 a
13 e
4 b
11 d
14 e
15 e
8 c
5 b
1 a

(所影响的行数为 10 行)


--第二次运行结果

(所影响的行数为 15 行)


(所影响的行数为 3 行)


(所影响的行数为 10 行)


(所影响的行数为 1 行)


(所影响的行数为 1 行)


(所影响的行数为 1 行)


(所影响的行数为 1 行)


(所影响的行数为 1 行)


(所影响的行数为 1 行)


(所影响的行数为 1 行)


(所影响的行数为 1 行)

c1 c2
---------- ----------
2 a
5 b
4 b
1 a
9 c
10 d
7 b
13 e
15 e
6 b

(所影响的行数为 10 行)

热点排行