Sqlite - Return 行,其中某些值不同

Sqlite - Return rows where some values are different

我有一个大型 table 学生考试成绩的 SQLite 数据库。学生经常重考失败的考试并随后通过考试,如下面的学生 10001 所示。

+─────────────+────────+──────────────+──────────+────────+─────────────+
| student_id  | level  | name         | outcome  | grade  | date        |
+─────────────+────────+──────────────+──────────+────────+─────────────+
| 10001       | Higher | Mathematics  | Pass     | A      | 01/04/2022  |
| 10001       | Higher | Mathematics  | Fail     | F      | 01/02/2022  |
| 10002       | Higher | English      | Pass     | B      | 01/04/2022  |
+─────────────+────────+──────────────+──────────+────────+─────────────+

我希望能够用这些数据做两件事。

  1. Return 只有失败的考试应该也有通过记录。换句话说,图像中从顶部开始的第 2 行 table.

  2. Return 整个 table 但这次 没有 最初的失败考试。换句话说,所有减去 1.

    的结果

如果student_id级别姓名[=35,则考试被视为补考=] 全部匹配。行中的其他值可以不同。

对于您想要的第一个结果集,您可以在 WHERE 子句中使用 EXISTS

SELECT t1.*
FROM tablename t1
WHERE t1.outcome = 'Fail'
  AND EXISTS (
        SELECT 1
        FROM tablename t2
        WHERE (t2.student_id, t2.level, t2.name) = (t1.student_id, t1.level, t1.name)
          AND t2.date > t1.date 
          AND t2.outcome = 'Pass'
      );

对于第二个结果集,因为要求是:

everything minus the results from 1

获取它的最简单方法是使用第一个查询和 EXCEPT:

SELECT * 
FROM tablename
EXCEPT
SELECT t1.*
FROM tablename t1
WHERE t1.outcome = 'Fail'
  AND EXISTS (
        SELECT 1
        FROM tablename t2
        WHERE (t2.student_id, t2.level, t2.name) = (t1.student_id, t1.level, t1.name)
          AND t2.date > t1.date 
          AND t2.outcome = 'Pass'
      );

参见demo

请注意,如果 table 中的日期格式与您问题中的示例数据相同,则这些日期不可比较。
您应该将格式更改为 YYYY-MM-DD.