参考SQL Query how to summarize students record by date?我能够得到我想要的报告。
在现实世界中,我被告知学生表将有3000万条记录。我有索引(StudentID,日期)。有任何改进性能的建议,还是有更好的方法来构建报告?
现在我有以下查询
;with cte as
(
select id,
studentid,
date,
'#'+subject+';'+grade+';'+convert(varchar(10), date, 101) report
from student
)
-- insert into studentreport
select distinct
studentid,
STUFF(
(SELECT cast(t2.report as varchar(50))
FROM cte t2
where c.StudentId = t2.StudentId
order by t2.date desc
FOR XML PATH (''))
, 1, 0, '') AS report
from cte c;
答案 0 :(得分:1)
如果没有看到执行计划,就不可能编写优化的SQL语句,因此我会提出建议。
不要使用cte,因为他们经常不处理大内存需要的查询(至少,根据我的经验)。相反,将cte数据放在实际表中,使用物化/索引视图或工作表(可能是大型临时表)。然后执行第二个选择(在cte之后)以将数据组合在有序列表中。
您的问题的评论数量表明您遇到了大问题(或问题)。您将高和瘦的数据(将整数,datetime2类型)转换为字符串中的有序列表。试着考虑以可用的最小数据格式存储并在之后(或从不)操作字符串。或者,请认真考虑创建XML数据字段以替换“报告”字段。
如果你可以使它工作,这就是我要做的(包括没有索引的测试用例)。您的里程可能会有所不同,但请尝试一下:
create table #student (id int not null, studentid int not null, date datetime not null, subject varchar(40), grade varchar(40))
insert into #student (id,studentid,date,subject,grade)
select 1, 1, getdate(), 'history', 'A-' union all
select 2, 1, dateadd(d,1,getdate()), 'computer science', 'b' union all
select 3, 1, dateadd(d,2,getdate()), 'art', 'q' union all
--
select 1, 2, getdate() , 'something', 'F' union all
select 2, 2, dateadd(d,1,getdate()), 'genetics', 'e' union all
select 3, 2, dateadd(d,2,getdate()), 'art', 'D+' union all
--
select 1, 3, getdate() , 'memory loss', 'A-' union all
select 2, 3, dateadd(d,1,getdate()), 'creative writing', 'A-' union all
select 3, 3, dateadd(d,2,getdate()), 'history of asia 101', 'A-'
go
select studentid as studentid
,(select s2.date as '@date', s2.subject as '@subject', s2.grade as '@grade'
from #student s2 where s1.studentid = s2.studentid for xml path('report'), type) as 'reports'
from (select distinct studentid from #student) s1;
我不知道如何使输出清晰,但结果集是2个字段。字段1是整数,字段2是XML,每个报告一个节点。这仍然不如发送结果集那么理想,但每个studentid至少有一个结果。