我有一个表,其中包括学生所选的每门课程的一行.我需要一个查询,它将返回一行数学和英语(学分为0),即使学生在那个学期没有修过这些课程.

我有表年级:

Student Year Term CourseTitle Subject Credit
1 2022 Trimester 1 Writing 1 English .5
1 2022 Trimester 1 Algebra 1 Math .5
1 2022 Semester 2 Writing 2 English .5
1 2022 Semester 2 PE 1 PE .5
1 2023 Semester 1 Reading 1 English .5
2 2020 Quarter 1 Algebra 1 Math .5
2 2020 Quarter 2 Algebra 2 Math .5
2 2020 Quarter 4 Biology Science .5

我想:

Student Year Term CourseTitle Subject Credit
1 2022 Trimester 1 Writing 1 English .5
1 2022 Trimester 1 Algebra 1 Math .5
1 2022 Semester 2 Writing 2 English .5
1 2022 Semester 2 NULL Math 0
1 2022 Semester 2 PE 1 PE .5
1 2023 Semester 1 Reading 1 English .5
1 2023 Semester 1 NULL Math 0
2 2020 Quarter 1 NULL English 0
2 2020 Quarter 1 Algebra 1 Math .5
2 2020 Quarter 2 NULL English 0
2 2020 Quarter 2 Algebra 2 Math .5
2 2020 Quarter 4 NULL English 0
2 2020 Quarter 4 NULL Math 0
2 2020 Quarter 4 Biology Science .5

我怎样才能做到这一点呢?

我试过了:

WITH MathEnglish AS 
(
    SELECT DISTINCT Subject
    FROM Grades
    WHERE Subject IN ('English', 'Math')
), Terms AS 
(
    SELECT DISTINCT Term
    FROM Grades
),  Combined AS 
(
    SELECT *
    FROM MathEnglish
    CROSS JOIN Terms
)
SELECT DISTINCT 
    Student, Year, 
    c.Term, g.CourseTitle,
    COALESCE(g.Subject, c.Subject), g.Credit
FROM 
    Combined c
FULL OUTER JOIN 
    Grades g ON c.Term = g.Term

...但这并不能解决问题.我需要一种不同的方法,但我不确定它是什么.

注:如果一个学生在一个学期里没有获得任何学分,我就不需要数学和英语行

菲德尔:http://sqlfiddle.com/#!18/000c2b/7

推荐答案

这很接近,但我们也希望包括before名学生组合而不是VIA FULL JOIN.对于每个学生组合,FULL JOIN仍然有一个占位符行,但ID值将为空,因此需要提前合并.

我们还希望在最后的联接上更精确,一旦我们这样做了,我们就不再需要最后的DISTINCT:

WITH Subjects AS (
    SELECT DISTINCT Subject
    FROM Grades
    WHERE Subject IN ('English', 'Math')
)
, Terms AS (
    SELECT DISTINCT Year, Term
    FROM Grades
)
, Students AS (
    SELECT DISTINCT Student
    FROM Grades
)
,  Combined AS (
    SELECT *
    FROM Subjects
    CROSS JOIN Terms
    CROSS JOIN Students
)
SELECT c.Student, c.Year, c.Term, c.Subject, g.CourseTitle, g.Credit
FROM  Combined c
LEFT JOIN Grades g ON c.Term = g.Term AND c.Subject = g.Subject AND c.Student = g.Student

任何值得使用的SIS(学生信息系统)也将为您提供一种获取条款、课程和学生的方法,而无需查看每个注册记录.

最后,我怀疑你不需要学生/学期的每一种可能的组合,只需要学生实际参与的组合(即使是在数学和英语以外的科目).通过这种方式,毕业、离开或以其他方式离开学校的学生不会在他们离开后或到达之前污染学期的结果.

如果是这样的话,看起来是这样的:

WITH Subjects AS (
    SELECT DISTINCT Subject
    FROM Grades
    WHERE Subject IN ('English', 'Math')
)
, StudentTerms AS (
    SELECT DISTINCT Student, Year, Term
    FROM Grades
)
,  Combined AS (
    SELECT *
    FROM Subjects
    CROSS JOIN StudentTerms
)
SELECT c.Student, c.Year, c.Term, c.Subject, g.CourseTitle, g.Credit
FROM  Combined c
LEFT JOIN Grades g ON c.Term = g.Term AND c.Subject = g.Subject AND c.Student = g.Student

Sql相关问答推荐

Select 最大值,但当并列时,从其他列 Select 最大值

在SQL中创建一个计数器,根据BigQuery/SQL中的条件递归地添加行值

Oracle SQL-将结果列在单行中

UPDATE查询中的乐观锁

用于过滤嵌套对象或数组中的JSON数据的WHERE条件

我可以在SQL的IN子句中使用比子查询包含的值更少的值吗?

从列中提取子字符串的ORDER BY CASE语句

我需要一个regexp_like来只验证字母D或T、数字和管道

合并分层表SQL中的第一个非空、变化的空位置

在UNION查询中查找MIN

同时插入和更新记录

从每月生成的系列中生成每日汇率

SQL根据另一列的顺序和值获取组中的最后一列

用替代方案替换 SQL Cursor 以提高性能

如何使用 Google BigQuery 中的条件根据特定列值连接列的 N 行?

SQL:无重复项的两个聚合函数

查询中获取审批者不起作用

正则表达式忽略特定数据部分的分隔符

如何 Select 一列具有最小值而另一列具有给定值的记录?

在 UTF 编码字符上应用 SQL LIKE 语句没有给出任何结果