SQL即使没有数据也返回行

时间:2014-10-16 12:53:44

标签: sql sql-server

我有一些学生在年底被授予A到E的成绩。我找到了使用以下SQL通过AssessmentCode分组的成绩的学生百分比。

SELECT '2014' as FileYear,
    AssessmentCode, 
    AssessResultsResult as Grade,
    cast(count(*)*100.0/sum(count(*)) over (partition by assessmentcode) as decimal(5,2))as GradePerc
FROM   vStudentReportsSemesterResults
WHERE  (FileYear = 2014) 
   AND (FileSemester = 2) 
   AND (AssessmentCode like '11%') 
   AND (AssessAreaHdgAbbrev2 = 'FinalGrade')

   group by AssessmentCode,
     AssessResultsResult

order by assessmentcode

这完美无缺,并返回......

FileYear  AssessmentCode   Grade   GradePerc
  2014       11CPSIPT        NULL     100
  2014       11CPSSDD        A        11.76
  2014       11CPSSDD        B        47.06
  2014       11CPSSDD        C        41.18
  2014       11DRADRA        NULL     100
  2014       11GEOGEO        A        6.25
  2014       11GEOGEO        B        56.25
  2014       11GEOGEO        C        28.13
  2014       11GEOGEO        D        9.38
  2014       11HISANC        NULL     100

请注意,有些评估代码尚未提交成绩(成绩栏中为NULL),而其他评估代码已提交成绩,但没有学生获得D或E。

即使尚未授予或提交成绩,有没有办法返回数据,例如

FileYear  AssessmentCode   Grade   GradePerc
  2014       11CPSIPT        A        0
  2014       11CPSIPT        B        0
  2014       11CPSIPT        C        0
  2014       11CPSIPT        D        0
  2014       11CPSIPT        E        0
  2014       11CPSSDD        A        11.76
  2014       11CPSSDD        B        47.06
  2014       11CPSSDD        C        41.18
  2014       11CPSSDD        D        0
  2014       11CPSSDD        E        0
  2014       11DRADRA        A        0
  2014       11DRADRA        B        0
  2014       11DRADRA        C        0
  2014       11DRADRA        D        0
  2014       11DRADRA        E        0
  2014       11GEOGEO        A        6.25
  2014       11GEOGEO        B        56.25
  2014       11GEOGEO        C        28.13
  2014       11GEOGEO        D        9.38
  2014       11GEOGEO        E        0

我想绘制这些信息的图表,并想知道某个等级是否未被授予等等。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

实现上述结果的一种方法是

WITH Results(FileYear,  AssessmentCode   ,Grade,   GradePerc)
AS
(
SELECT 
    '2014' AS FileYear,
    AssessmentCode, 
    AssessResultsResult as Grade,
    CAST(COUNT(*)*100.0/SUM(COUNT(*)) OVER (PARTITION BY assessmentcode) AS DECIMAL(5,2))AS GradePerc
FROM
    vStudentReportsSemesterResults
WHERE  
    (FileYear = 2014) 
    AND 
    (FileSemester = 2) 
    AND 
    (AssessmentCode like '11%') 
    AND 
    (AssessAreaHdgAbbrev2 = 'FinalGrade')
GROUP BY 
    AssessmentCode,
    AssessResultsResult
),
MyGrades(Grade)
AS
(
SELECT
    'A'
UNION ALL
SELECT
    'B'
UNION ALL
SELECT
    'C'
UNION ALL
SELECT
    'D'
UNION ALL
SELECT
    'E'
),
FinalResults(FileYear, AssessmentCode, Grade, GradePerc)
AS
(
    SELECT
        FileYear,
        AssessmentCode,
        CASE WHEN Results.Grade IS NULL THEN MyGrades.Grade ELSE Results.Grade END AS Grade,
        CASE WHEN Results.Grade IS NULL THEN 0 ELSE Results.GradePerc END AS GradePerc
    FROM
        Results 
        LEFT JOIN MyGrades
            ON Results.Grade IS NULL
    UNION ALL
    SELECT
        FileYear,
        AssessmentCode,
        MyGrades.Grade,
        0 AS GradePerc
    FROM
        MyGrades
        LEFT JOIN Results
            ON Results.Grade != MyGrades.Grade
)

SELECT
    FileYear,
    AssessmentCode,
    Grade,
    MAX(GradePerc) AS GradePerc
FROM
    FinalResults
GROUP BY
    FileYear,
    AssessmentCode,
    Grade
ORDER BY 
    AssessmentCode
    ;

答案 1 :(得分:0)

如果你可以操纵数据库对象......

我不知道你的表结构是什么样的,但是我建议你创建一个存储你可能等级(A到E)的表,并使vStudentReportsSemesterResults.AssessResultsResult成为一个外键列。 (因为它看起来像一个视图而不是一个表,所以你需要使用基础表来执行此操作。)现在,您可以外连接到新表并获取该表中每个值的结果。作为奖励,如果您从“E”更改为“F”或者评分系统发生变化,您将无需调整查询,因为其中没有任何内容是硬编码的。

如果你无法操纵数据库对象......

您可以将此查询作为存储过程(或脚本)的一部分,并创建一个临时表(或本地表变量)并加入其中。但这个概念仍然是一样的。