当前位置: 代码迷 >> Sql Server >> MS Server高级排序有关问题
  详细解决方案

MS Server高级排序有关问题

热度:18   发布时间:2016-04-24 10:22:21.0
MS Server高级排序问题
--表A
--ID   SetTime,      SetName
--1,  2014-06-21   C30
--2,  2014-06-23   C35
--3,  2014-08-01   C30
--4,  2014-09-03     C35
--5,  2014-06-19     C30
--6,  2014-06-22     C35
--7,  2014-06-16     C10
--8,  2014-05-13   C15
--9,  2014-05-05   C20
--10,  2014-05-01    C40
--11,  2014-05-03   C45
--13,  2014-05-04   C25
--我要的结果是
--ID   SetTime,      SetName
--1,  2014-06-21   C30   注意:小于当前时间的最大时间值
--2,  2014-08-01   C30   注意:大于当前时间
--3,  2014-06-19     C30        
--4,  2014-06-23   C35
--5,  2014-09-03     C35
--6,  2014-06-22     C35
--7,  2014-05-01     C40      注意:剩余的都是升序
--8,  2014-05-03   C45
--9,  2014-05-04   C25
--10, 2014-05-05   C20
--11, 2014-05-13   C15
--12, 2014-06-16     C10
有的SetName会有多个值相同,比如说C30,注意看C30对应的SetTime时间, 小于当前时间的最大时间值排在第一位,大于当前时间的排在第二位,小于当前时间的最小时间值排在最后,以此类推
------解决方案--------------------

with tb(id, settime, setname)
as(
select
1, '2014-06-21', 'C30' union all select
2, '2014-06-23', 'C35' union all select
3, '2014-08-01', 'C30' union all select
4, '2014-09-03', 'C35' union all select
5, '2014-06-19', 'C30' union all select
6, '2014-06-22', 'C35' union all select
7, '2014-06-16', 'C10' union all select
8, '2014-05-13', 'C15' union all select
9, '2014-05-05', 'C20' union all select
10, '2014-05-01', 'C40' union all select
11, '2014-05-03', 'C45' union all select
13, '2014-05-04', 'C25'
)
,tc as(
select *,
ROW_NUMBER()  over(partition by setname,(case when datediff(day,settime,GETDATE())<0 
then -1 when datediff(day,settime,GETDATE())>0 then 1 else 0 end) 
order by abs(datediff(day,settime,GETDATE())))num from tb a
)
select id=ROW_NUMBER() over(order by 
case when (select COUNT(1) from tc where a.setname=setname)>1 then 2 else 1 end desc,
(select MIN(settime) from tc where a.setname=setname),
case when datediff(day,settime,GETDATE())>0 then num*2-1 else num*2 end)
,settime,setname from tc a

------解决方案--------------------
费老劲了,楼主再看看

create table #t(id int, settime date, setname varchar(3));
insert into #t
select
1, '2014-06-21', 'C30' union all select
2, '2014-06-23', 'C35' union all select
3, '2014-08-01', 'C30' union all select
4, '2014-09-03', 'C35' union all select
5, '2014-06-19', 'C30' union all select
6, '2014-06-22', 'C35' union all select
7, '2014-06-16', 'C10' union all select
8, '2014-05-13', 'C15' union all select
9, '2014-05-05', 'C20' union all select
10, '2014-05-01', 'C40' union all select
11, '2014-05-03', 'C45' union all select
13, '2014-05-04', 'C25';
--select * from #t;
;with t1 as
(
select setname,
  MAX(case when settime<GETDATE() then settime end) as settime1
  , MAX(case when settime>GETDATE() then settime end) as settime2
  , MIN(case when settime<GETDATE() then settime end) as settime3
  , COUNT(setname) as ct
from #t
group by setname
--order by settime1
), t2 as
(
select setname, settime1 settime, ct, px=1 from t1
where settime1 is not null
union
select setname, settime2, ct, px=2 from t1
where settime2 is not null
union
select setname, settime3, ct, px=3 from t1
where settime3 is not null and settime3<>settime1
--order by setname, px
), t3 as
(
select setname
  , settime
  , case when ct=1 then 'z' + convert(char(10),settime,120)
         else setname + rtrim(px)
  相关解决方案