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

一个很复杂的sql语句,来给修改一下

2012-01-14 
一个很复杂的sql语句,高手请进来给修改一下hot表:gsid不重复,可以增加记录,用来设置该公司的信息被推荐idg

一个很复杂的sql语句,高手请进来给修改一下
hot表:gsid不重复,可以增加记录,用来设置该公司的信息被推荐 
id gsid 
1 123 
2 234 
3 345 

xxb表:是用户信息发布表,gsid重复出现,bz用来设置该信息被推荐 
id gsid cpmc bz date 
1 123 aaa 0  
2 123 aaa 0  
3 234 bbb 0  
4 345 ccc 0  
5 345 ccc 0  
6 456 ddd 0  
7 665 eee 1  
8 666 fff 0  
9 667 ggg 1  
10 668 hhh 1  
   
  实现:1、取出xxb的id,gsid,cpmc,bz,date字段 
  2、只取5条记录,按照xxb.date排序,必须保持5条记录 
  3、优先取hot表中gsid的一条记录,也就是一个gsid只取一条记录,且只取改gsid里日期最新的一条 (不一定就是id最大,用户可能修改记录)
  4、假如满足hot表的gsid的记录不够5条,则取xxb.bz=1的记录补足5条 



[解决办法]
??

SQL code
declare @v varchar(1000)select top 5 aa.* into tmp from hot a left join (select * from xxb a where not exists(select 1 from xxb where gsid=a.gsid and date>a.date)) aa on a.gsid=aa.gsid where aa.gsid is not nullif @@rowcount<5 begin    set @v='insert tmp select top '+ltrim(5-@@rowcount)+' * from xxb where bz=1'    exec(@v)endselect * from tmpdrop table tmp
[解决办法]
1、取出xxb的id,gsid,cpmc,bz,date字段
select * from xxb 

2、只取5条记录,按照xxb.date排序,必须保持5条记录
select top 5 * from xxb order by date 

3、优先取hot表中gsid的一条记录,也就是一个gsid只取一条记录,且只取改gsid里日期最新的一条 (不一定就是id最大,用户可能修改记录) 
select hot.gsid , max(date) date from hot , xxb where hot.gsid = xxb.gsid

如果取所有字段

select a.* from
(
select hot.*,xxb.* from hot.gsid = xxb.gsid
) a,
(
select hot.gsid , max(date) date from hot , xxb where hot.gsid = xxb.gsid
) b
where a.gsid = b.gsid and a.date = b.date

4、假如满足hot表的gsid的记录不够5条,则取xxb.bz=1的记录补足5条
这个没看懂。

[解决办法]
你的表里是不是少一个时间字段
这个是你想要的结果吗?
SQL code
select top 5 id,gsid,cpmc,bz,date from xxb where gsid=(select gsid from hot a where not exists(select gsid from hot where 日期>a.日期)) or bz=1 group by bz
[解决办法]
[code=SQL][/code]

declare @a table(id int,gsid int)
insert into @a
select 1,123
union all select 2,234
union all select 3,345
declare @b table(id int,gsid int,cpmc varchar(10),bz int,date datetime)
insert into @b
select 1,123,'aaa',0,'2006-1-3'
union all select 2,123,'aaa',0,'2007-5-6'
union all select 3,234,'bbb',0,'2007-3-6'
union all select 4,345,'ccc',0,'2007-5-10'
union all select 5,345,'ccc',0,'2007-8-7'
union all select 6,456,'ddd',0,'2007-5-7'
union all select 7,665,'eee',1,'2007-3-4'
union all select 8,666,'ggg',0,'2007-1-6'
union all select 9,667,'ggg',1,'2007-12-7'
union all select 10,559,'hhh',1,'2007-10-8'

create table #b(id int,gsid int,cpmc varchar(10),bz int,date datetime)

insert into #b
select bb.* from(
select b.gsid,date=max(date) from @a a,@b b where a.gsid=b.gsid group by b.gsid
) aa,@b bb where bb.date=aa.date

declare @c int,@sql nvarchar(1000)
select @sql='select @d=count(*) from #b q '
exec sp_executesql @sql,N'@d int output',@c output
select @c

if @c<5
begin
insert into #b
select b.* from @b b where b.bz=1 order by b.id
select top 5 * from #b
end


else 
begin
select top 5 * from #b
end



[解决办法]
以下是测试楼主要的效果,调用时可用临时表处理:

SQL code
declare @a table(id int ,gsid int )insert  into @aselect  1,123union all select 2,234union all select 3,345declare @b table(id int ,gsid int ,cpmc varchar(10),bz int ,[date] datetime)insert  into @b     select 1,123,'aaa',0,'2006-1-3'union all select 2,123,'aaa',0,'2007-5-6'union all select 3,234,'bbb',0,'2007-3-6'union all select 4,345,'ccc',0,'2007-5-10'union all select 5,345,'ccc',0,'2007-8-7'union all select 6,456,'ddd',0,'2007-5-7'union all select 7,665,'eee',1,'2007-3-4'union all select 8,666,'ggg',0,'2007-1-6'union all select 9,667,'ggg',1,'2007-12-7'union all select 10,559,'hhh',1,'2007-10-8'---row=1记录是满足hot表的gsid的记录select     t.*from     (select top 5 *,1 as row  from @b b where [date]=(select max([date]) from @b  where gsid=b.gsid) order by [date] desc)tjoin     @a a on t.gsid=a.gsidunion allselect * ,2 as row from @b where bz=1  and ID not in(select     t.IDfrom     (select top 5 *,1 as row  from @b b where [date]=(select max([date]) from @b  where gsid=b.gsid) order by [date] desc)tjoin     @a a on t.gsid=a.gsid)(所影响的行数为 3 行)(所影响的行数为 10 行)id          gsid        cpmc       bz          date                                                   row         ----------- ----------- ---------- ----------- ------------------------------------------------------ ----------- 5           345         ccc        0           2007-08-07 00:00:00.000                                12           123         aaa        0           2007-05-06 00:00:00.000                                17           665         eee        1           2007-03-04 00:00:00.000                                29           667         ggg        1           2007-12-07 00:00:00.000                                210          559         hhh        1           2007-10-08 00:00:00.000                                2(所影响的行数为 5 行)
[解决办法]
select top 5 c.* from
xxb c,
(select a.gsid,a.bz,max(a.date) date,
from xxb a,(select top 5 * from gsid order by id) b
where a.gsid=b.gsid 
group by a.gsid,a.bz) d --d表查出日期最大的gsid属于hot表的记录
where c.gsid=d.gsid
order by c.bz,c.gsid
[解决办法]
走两步:)

先取 每一个 gsid 对应的时间对大的一条记录, 那么可以用 not exists或者与 分组聚合后的行集进行连结得到. 这得到了第一批数据行

再取 bz=1,且不在第一个数据行集中出现的记录 的集合

对上面两个行集进行union操作,再取前5条.

为保证第一个行集的数据行优先出先,则给两个行集均指定一个排序优先级
比如
select top 5 * from
(
select *, PRI=0 ... --第一个行集
union select *,RPI=1 ... --第二个行集
) x
order by PRI

[解决办法]
支持一下。
UP
!!!

热点排行