2017-05-27 58 views
0

这里的数据:SQL为每个组查找列顺序由另一列

studentid,state,score,date,modno,transactionno 
1,IL,10,20170101,0,0 
1,VA,20,20170102,1,1 
1,FL,30,20170103,2,2 
2,VA,40,20170101,0,0 
2,IL,50,20170102,1,1 
2,IN,60,20170103,2,2 

这里的输出应该是这样:

studentid,state,score,date 
1,IL,20,20170101 
2,VA,60,20170102 

所以基本上我们通过studentid要组。

根据最低的modno和transactionno查找第一个状态。

根据最高的modno和transactionno查找第一个分数。

select studentid, 
     (select top 1 state from student s1 where s.studentid = s1.studentid order by modno, transactionno) as state, 
     (select top 1 score from student s1 where s.studentid = s1.studentid order by modno desc, transactionno desc) as score, 
     (select top 1 date from student s1 where s.studentid = s1.studentid order by modno, transactionno) as date 
from student s 
group by studentid 

以上是我在SQL 2008中的查询。是否有其他方法来编写此查询以获得更好的性能?当处理大型数据集并且每组拉出两个以上的列时,它真的会显示出来。

+0

为什么一个'studentid'列有在'student'表中的多个行? –

+0

我不理解输出。应该使用什么*日期*为什么20为id - 1?它不应该是30吗? – Parfait

回答

0

我想我会用条件汇总处理这个:

select studentid, 
     max(case when seqnum_asc = 1 then state end) as state, 
     max(case when seqnum_desc = 1 then score end) as score, 
     max(case when seqnum_asc = 1 then date end) as date 
from (select s.*, 
      row_number() over (partition by studentid order by modno, transactionno) as seqnum_asc, 
      row_number() over (partition by studentid order by modno desc, transactionno desc) as seqnum_desc 
     from student s 
    ) s 
group by studentid; 
0

猜猜你的输出是不正确的,或者我们没有带在你的输出unserdtood日期部分。

试试这个其他的样本数据,让我们知道,

declare @t table(studentid int,states varchar(20), score int 
,dates date,modno int,transactionno int) 

insert into @t VALUES 
(1,'IL',10,'20170101',0,0) 
,(1,'VA',20,'20170102',1,1) 
,(1,'FL',30,'20170103',2,2) 
,(2,'VA',40,'20170101',0,0) 
,(2,'IL',50,'20170102',1,1) 
,(2,'IN',60,'20170103',2,2) 
;with CTE as 
(
select studentid from @t 
group by studentid 
) 
SELECT t.studentid,ca.states,ca1.score,ca.dates 
from CTE t 
cross apply(select top 1 t1.states,t1.dates from @t t1 
where t.studentid=t1.studentid 
order by modno,transactionno)ca 
cross apply(select top 1 t1.score from @t t1 
where t.studentid=t1.studentid 
order by modno desc,transactionno desc)ca1 
--cross apply(select top 1 t1.dates from @t t1 
--where t.studentid=t1.studentid 
--order by modno ,transactionno )ca2