这个SqlServer 存储过程怎么写?

时间:2022-03-29 14:05:48
Table A
TypeId  TypeName
1000    类别1
1001    类别2
1002    类别3

Table B
InfoId  TypeId  InfoName
10000   1000    信息1
10001   1000    信息2
10002   1001    信息3
…………
10512   1002    信息512
…………

最后需要的效果
类别1     类别2     类别3
信息1     信息3     信息512
信息2     信息4     信息514
……       ……       ……

我要在页面上显示3个类别,每个类别随机抽取5条信息出来。我们以前做的是在程序中先读取类别,然后再根据类别的编号找相应的信息记录,那么这个至少要多次连接数据库。我想通过存储过程一次性把“类别的记录”和相应的“每个类别的随机5条记录”全部读取出来,然后再到程序端来处理,请问怎么写?怎么能循环的巴每个类别的记录读取出来,然后再合并到一个表中?最好效率高一点,不要用临时表

9 个解决方案

#1



select 

from 
b t 
join 
a t2 on t2.TypeID=t.TypeID 
where TypeName in('类别1','类别2','类别3') and
t2.InfoId in(select top 5 InfoId from b where TypeID=t.TypeID order by newID())

#2


好像又是行转列.hehe

#3


随机抽取有什么规则,总不能每次都前5条吧

#4


好像又是行转列.hehe
--------------------
不是行列转换这么简单,还包括信息重组。


随机抽取有什么规则,总不能每次都前5条吧
------------
随即抽取就是规则,每次都前5条也叫随机?

#5


每组取前n条

行转列


还是行转列. 都是天天问天天答的问题了.

#6


create table A(TypeId char(4),    TypeName nvarchar(10))
insert A select 1000,         '类别1' 
insert A select 1001,         '类别2' 
insert A select 1002,         '类别3' 
insert A select 1003,         '类别4' 

go
create Table   B (InfoId char(5),    TypeId char(4),    InfoName nvarchar(10))
insert B select 10000,       1000,         '信息1' 
insert B select 10001,       1000,         '信息2' 
insert B select 10002,       1000,         '信息3' 
insert B select 10003,       1000,         '信息4' 
insert B select 10004,       1000,         '信息5' 
insert B select 10005,       1001,         '信息6' 
insert B select 10006,       1001,         '信息7' 
insert B select 10007,       1001,         '信息8' 
insert B select 10008,       1001,         '信息9' 
insert B select 10009,       1001,         '信息10' 
insert B select 10010,       1002,         '信息11' 
insert B select 10011,       1002,         '信息12' 
insert B select 10012,       1002,         '信息12' 
insert B select 10013,       1002,         '信息14' 
insert B select 10014,       1002,         '信息15' 
insert B select 10015,       1002,         '信息16' 
insert B select 10016,       1003,         '信息17' 

go



create proc test(@Name nvarchar(1000))
as

--declare @Name nvarchar(1000)
--set @Name='''类别1'',''类别2'',''类别3'''

create table #(InfoId char(5),TypeName nvarchar(10),InfoName nvarchar(10),row int)
exec('
declare Test cursor for
select TypeId,TypeName from A where TypeName in ('+@Name+')
declare @TypeId char(4),@TypeName nvarchar(10)
open test
fetch next from test into @TypeId,@TypeName
while @@fetch_status=0
begin
insert # select top 3 InfoId,@TypeName,InfoName,row=1 from b where TypeId=@TypeId order by newID()
fetch next from test into @TypeId,@TypeName
end
close test
deallocate test')

update a
set row=(select count(1) from # where TypeName=a.TypeName and InfoId!>a.InfoId)
from # a



declare @s2 nvarchar(4000)
set @s2=''
select @s2= @s2+','+quotename(TypeName)+'=max(case when TypeName='+quotename(TypeName,'''')+' then InfoName end)'
from #
group by TypeName
set @s2=stuff(@s2,1,1,'')
exec('select '+@s2+' from # group by row')

go
exec test @Name='''类别1'',''类别2'',''类别3'''
--
--drop proc test
--drop table a,b
/*

(所影响的行数为 9 行)

类别1        类别2        类别3        
---------- ---------- ---------- 
信息1        信息6        信息11
信息2        信息8        信息12
信息5        信息9        信息14

(所影响的行数为 3 行)
*/

#7


--测试一个取随机三条,改为5条就行了...

#8


直接用in随机用点问题。。所以改为游标

#9


似乎不用这么复杂,思路:

3个子结果集——各随机N条,按行号1对1联接起来就是了。

#1



select 

from 
b t 
join 
a t2 on t2.TypeID=t.TypeID 
where TypeName in('类别1','类别2','类别3') and
t2.InfoId in(select top 5 InfoId from b where TypeID=t.TypeID order by newID())

#2


好像又是行转列.hehe

#3


随机抽取有什么规则,总不能每次都前5条吧

#4


好像又是行转列.hehe
--------------------
不是行列转换这么简单,还包括信息重组。


随机抽取有什么规则,总不能每次都前5条吧
------------
随即抽取就是规则,每次都前5条也叫随机?

#5


每组取前n条

行转列


还是行转列. 都是天天问天天答的问题了.

#6


create table A(TypeId char(4),    TypeName nvarchar(10))
insert A select 1000,         '类别1' 
insert A select 1001,         '类别2' 
insert A select 1002,         '类别3' 
insert A select 1003,         '类别4' 

go
create Table   B (InfoId char(5),    TypeId char(4),    InfoName nvarchar(10))
insert B select 10000,       1000,         '信息1' 
insert B select 10001,       1000,         '信息2' 
insert B select 10002,       1000,         '信息3' 
insert B select 10003,       1000,         '信息4' 
insert B select 10004,       1000,         '信息5' 
insert B select 10005,       1001,         '信息6' 
insert B select 10006,       1001,         '信息7' 
insert B select 10007,       1001,         '信息8' 
insert B select 10008,       1001,         '信息9' 
insert B select 10009,       1001,         '信息10' 
insert B select 10010,       1002,         '信息11' 
insert B select 10011,       1002,         '信息12' 
insert B select 10012,       1002,         '信息12' 
insert B select 10013,       1002,         '信息14' 
insert B select 10014,       1002,         '信息15' 
insert B select 10015,       1002,         '信息16' 
insert B select 10016,       1003,         '信息17' 

go



create proc test(@Name nvarchar(1000))
as

--declare @Name nvarchar(1000)
--set @Name='''类别1'',''类别2'',''类别3'''

create table #(InfoId char(5),TypeName nvarchar(10),InfoName nvarchar(10),row int)
exec('
declare Test cursor for
select TypeId,TypeName from A where TypeName in ('+@Name+')
declare @TypeId char(4),@TypeName nvarchar(10)
open test
fetch next from test into @TypeId,@TypeName
while @@fetch_status=0
begin
insert # select top 3 InfoId,@TypeName,InfoName,row=1 from b where TypeId=@TypeId order by newID()
fetch next from test into @TypeId,@TypeName
end
close test
deallocate test')

update a
set row=(select count(1) from # where TypeName=a.TypeName and InfoId!>a.InfoId)
from # a



declare @s2 nvarchar(4000)
set @s2=''
select @s2= @s2+','+quotename(TypeName)+'=max(case when TypeName='+quotename(TypeName,'''')+' then InfoName end)'
from #
group by TypeName
set @s2=stuff(@s2,1,1,'')
exec('select '+@s2+' from # group by row')

go
exec test @Name='''类别1'',''类别2'',''类别3'''
--
--drop proc test
--drop table a,b
/*

(所影响的行数为 9 行)

类别1        类别2        类别3        
---------- ---------- ---------- 
信息1        信息6        信息11
信息2        信息8        信息12
信息5        信息9        信息14

(所影响的行数为 3 行)
*/

#7


--测试一个取随机三条,改为5条就行了...

#8


直接用in随机用点问题。。所以改为游标

#9


似乎不用这么复杂,思路:

3个子结果集——各随机N条,按行号1对1联接起来就是了。