简体   繁体   English

我如何为附加的报告编写SQL?

[英]How would I go about writing the SQL for the attached report?

We're moving from data system to another. 我们正在从数据系统转向另一个。 I'm having to rewrite some reports the new system has a custom reporting module where you can write a query and paste it into a window and push it out to the end user. 我不得不重写一些报告,新系统有一个自定义报告模块,您可以在其中编写查询并将其粘贴到窗口中并将其推送给最终用户。 I have one report that all of users have been requesting but I can't figure out how to write it. 我有一个报告,所有用户都在请求,但我无法弄清楚如何编写它。

It breaks it down the school population by grade level, gender and race. 它按年级,性别和种族划分了学校人口。 see attached below. 见下文附件。

在此输入图像描述

I wrote this which breaks down the population by grade level but not sure where to go from here. 我写了这个,按年级分解人口,但不知道从哪里开始。

SELECT
gl.title as Grade,
COUNT (s.student_id)
FROM
students s,
student_enrollment se,
school_gradelevels gl
WHERE
s.student_id = se.student_id
AND se.school_id=gl.school_id
AND se.grade_id=gl."id"
AND se.syear =2012
AND se.end_date IS NULL
AND se.school_id =10

group by gl.title

order by Grade;

For reference gender is s.gender and race is s.race. 作为参考,性别是s.gender,种族是s.race。 I'm wondering if were going to have to purchase a reporting software like crystal reports. 我想知道是否需要购买像水晶报告这样的报告软件。

There is no data example so would presum that the gender and race information is captured against the student. 没有数据示例,因此可以预测性别和种族信息是针对学生捕获的。

What you want to do is get an initial table that would look like that: 你想要做的是获得一个看起来像这样的初始表:

GradeLevel   |   Category     |  NumOfStudents
------------------------------------------------
PK           |     B - Male   |  10
PK           |     B - Female |  12
0            |     B - Male   |  5
0            |     B - Female |  6

This is easy to achieve by doing something like that: 这样做很容易实现:

SELECT
gl.title as GradeLevel,
s.Race + '-' +s.Gender as Category
COUNT (s.student_id) as NumOfStudents
FROM 
           students s,
inner join student_enrollment se on s.student_id = se.student_id,
inner join school_gradelevels gl on se.school_id=gl.school_id AND se.grade_id=gl."id"
WHERE
    se.syear =2012
AND se.end_date IS NULL
AND se.school_id =10

group by gl.title, s.Race + '-' +s.Gender

order by Grade;

next you would want to make a Pivot out of that data by using your reporting tool weather its SSRS or Crystal or anything else that supports matrix reports. 接下来,您希望通过使用报告工具来使用其SSRS或Crystal或支持矩阵报告的任何其他内容,从数据中提取数据。

if there is no report tool available that knows how to make a matrix use the SQL Pivot clause: http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx 如果没有可用的报表工具知道如何使矩阵使用SQL Pivot子句: http//msdn.microsoft.com/en-us/library/ms177410( Pivot = sql.105).aspx

SELECT GradeLevel, [B-Male], [B-Female] ....
FROM 
  (
      SELECT
      gl.title as GradeLevel,
      s.Race + '-' +s.Gender as Category
      COUNT (s.student_id) as NumOfStudents
      FROM 
                 students s,
      inner join student_enrollment se on s.student_id = se.student_id,
      inner join school_gradelevels gl on se.school_id=gl.school_id AND se.grade_id=gl."id"
      WHERE
          se.syear =2012
      AND se.end_date IS NULL
      AND se.school_id =10
      group by gl.title, s.Race + '-' +s.Gender   
  ) rawData
  PIVOT
  (
  SUM(NumOfStudents)
  FOR Category IN ( [B-Male], [B-Female], ... )
) AS pvt 

Fundamentally, you must group by everything you're counting, which appears to be grade, race, and sex. 从根本上说,你必须按照你所计算的一切进行分组,这似乎是年级,种族和性别。 Do that first: get everything in rows, summed up the way you need. 先做到这一点:把所有东西都排成行,总结你需要的方式。

What may be confusing you is that the report has two levels of grouping: one by grade, race, and sex, and one by grade & race. 令你困惑的是,该报告有两个级别的分组:一个是分级,种族和性别,一个是分级和种族。 In effect, it looks like this: 实际上,它看起来像这样:

create view V as 
SELECT   gl.title as Grade
       , s.sex
       , s.race 
       , COUNT (s.student_id) as Q
FROM students as s
JOIN student_enrollment as se
ON s.student_id = se.student_id
JOIN school_gradelevels gl
ON se.school_id = gl.school_id
AND se.grade_id = gl.id
WHERE
    se.syear = 2012
AND se.end_date IS NULL
AND se.school_id = 10
group by gl.title, s.sex, s.race

select Grade, race, sex, Q
from V
UNION
select Grade, race, 'Z', sum(Q) as Q
from V
group by Grade, race

How you turn that into a cross-tab report depends on the tools at your disposal. 如何将其转换为交叉表报告取决于您可以使用的工具。 It's possible in SQL, using the pivot operator or a series of case s in your select . 在SQL中,可以使用pivot操作符或select的一系列case The trick is to notice you need three columns for every race: male, female, and both. 诀窍是要注意每个种族需要三列:男性,女性和两者。 It's a little tedious, here's a sample 这有点单调乏味,这是一个样本

select   Grade, 1 as sort_order  
       , max(case race when 1 then 
                  case sex when 'M' then Q end end) as r1mq
       , NULL as r1mb
       , max(case race when 1 then 
                  case sex when 'F' then Q end end) as r1fq
       , max(case race when 2 then 
                  case sex when 'M' then Q end end) as r2mq
       , NULL as r2mb
       , max(case race when 2 then 
                  case sex when 'F' then Q end end) as r2fq
       ...
from V group by Grade
UNION
select   Grade, 2 as sort_order  
       , NULL as r1mq
       , max(case race when 1 then 
                  case sex when 'Z' then Q end end) as r1bq
       , NULL as r1fq
       , NULL as r2mq
       , max(case race when 2 then 
                  case sex when 'Z' then Q end end) as r2bq
       , NULL as r2fq
       ...
from V group by Grade
order by Grade, sort_order

That produces two rows per grade, with the combined student totals in the second row for each one. 每个等级产生两行,每个行的第二行合并学生总数。

You get the idea. 你明白了。 You'll also need queries to count students grouped by grade and sex, and by grade alone. 您还需要查询来统计按年级和性别分组的学生,以及仅按年级分组。 Those could be joined to the output of your pivot query. 这些可以加入您的数据透视查询的输出。 And totals by race, for the bottom row, unioned on with grade of 99 or something to make it sort at the bottom. 对于排在最后一排的比赛总数,以99或者等级联合起来,使其排在最底层。 The result would match the row & column layout of your report. 结果将与报表的行和列布局相匹配。

with detail as (
    select
        gl.title as grade, s.race, s.gender, count(s.student_id) total
    from
        students s
        inner join
        student_enrollment se using (student_id)
        inner join
        school_gradelevels gl on se.school_id = gl.school_id and se.grade = gl.id
    where
        and se.syear = 2012
        and se.end_date is null
        and se.school_id = 10
    group by 1, 2, 3
    order by 1, 2, 3
) agg as (
    select grade, array_agg(total) total
    from detail
    group by grade
)
select
    grade,
    (select sum(e) from unnest(total) s(e)) total_grade,
    total[1,1] + total[2,1] + total[3,1] + total[4,1] + total[5,1] + total[6,1] total_F,
    total[1,2] + total[2,2] + total[3,2] + total[4,2] + total[5,2] + total[6,2] total_M,
    total[1,1] total_A_F,
    total[1,2] total_A_M,
    total[1,1] + total[1,2] total_A,
    total[2,1] total_B_F,
    total[2,2] total_B_M,
    total[2,1] + total[2,2] total_B,
    total[3,1] total_H_F,
    total[3,2] total_H_M,
    total[3,1] + total[3,2] total_H,
    total[4,1] total_I_F,
    total[4,2] total_I_M,
    total[4,1] + total[4,2] total_I,
    total[5,1] total_M_F,
    total[5,2] total_M_M,
    total[5,1] + total[5,2] total_MM,
    total[6,1] total_W_F,
    total[6,2] total_W_M,
    total[6,1] + total[6,2] total_W,
from agg

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM