2017-01-17 22 views
4

我有一个数据库与学生信息和学校成绩。然后,我试图查询显示关键绩效指标的结果集,以反映我们在学校中不同的学生子群体。最终结果的一个非常粗略的例子是:T-SQL - 更好的替代联盟所有的分组分析

例表我想创建
注意到,学生群体有重叠。
同样的学生可以被包含在Whole YearFemalesNon FSM等:

enter image description here

现在我已经实现了这一点。我已经为每个子组使用了聚合函数和GROUP BY子句,然后使用UNION ALL将这些查询组合起来创建表。我的代码的一个粗略的例子是:

SELECT 'Whole Year' AS [Group], COUNT(student.name) AS [Total No. of Students] 

UNION ALL 

SELECT student.gender AS [Group], COUNT(student.name) AS [Total No. of Students] 
GROUP BY student.gender 

UNION ALL 

SELECT student.fsm AS [Group], COUNT(student.name) AS [Total No. of Students] 
GROUP BY student.fsm 

问题是,我需要为许多关键性能指标和许多子组做这个。用我目前的解决方案,我的代码非常庞大,而且不易管理。

我猜测可能有一个更优雅的解决方案,所以如果任何人都可以指出我在正确的方向,我将非常感激。

+0

很难说如果没有看到所有的代码,但如果你阅读总结数据'累积'读它可能是你要找的: https://technet.microsoft.com/ en-us/library/ms189305(v = sql.90).aspx – MightyRearranger

+0

列是动态的,基于“学校成绩”中的条目数量? (即%与C +,B +,A + ...等)? –

+0

MightRearranger感谢您的链接。在阅读了我和CUBE运营商一起玩的文章后,如果strickt01没有回答,它可能会达到我想要的。 –

回答

2

首先,您需要将您的分组创建为行。目前它们是基于列的(它们基于student中的列值)。因此,使用UNPIVOT运算符将列转换为行,每个分组保存所有属于它的学生ID。

通过将这种映射到一个CTE(本质上是一个临时表),那么你可以从这个加入到student和计算你的KPI为每个分组:

; 
with group_cte (student_group_name, student_id) 
AS 
(
    select student_group, student_id 
    from 
    (select e.student_id as total, 
     case when gender = 'male' then e.student_id end as males, 
     case when gender = 'females' then e.student_id end as females, 
     -- your other groupings 
    from student e) p 
    UNPIVOT 
    (student_id for student_group 
     in (total, males, females)) unpvt 
) 
select student_group_name, count(student_id), -- your KPIs... 
from group_cte c 
inner join student s 
on e.student_id = c.student_id 
group by student_group_name 

这将导致少得多表扫描和清洁SQL。

+0

这已经很好地解决了我的问题,谢谢。我在我的环境中重新生成了这个查询,它完全符合我的需要。我必须承认,这是我第一次使用CTE或unpivot,而且我还没有完全理解查询(还)中发生了什么。非常感谢,再次感谢。 –

+0

没问题。一个令人愉快的挑战!我已经修改了答案,试图澄清查询的工作。然而,运行每个组件'SELECT'永远不会有任何替代品,以便了解它是如何构建的。 – strickt01