涉及连续值的棘手SQL查询

Gab*_*iel 8 mysql sql database

我需要执行一个相对容易解释但(考虑到我的技能有限)难以编写SQL查询.

假设我们有一个类似于这个的表:

 exam_no | name | surname | result | date
---------+------+---------+--------+------------
 1       | John | Doe     | PASS   | 2012-01-01
 1       | Ryan | Smith   | FAIL   | 2012-01-02 <--
 1       | Ann  | Evans   | PASS   | 2012-01-03
 1       | Mary | Lee     | FAIL   | 2012-01-04
 ...     | ...  | ...     | ...    | ...
 2       | John | Doe     | FAIL   | 2012-02-01 <--
 2       | Ryan | Smith   | FAIL   | 2012-02-02
 2       | Ann  | Evans   | FAIL   | 2012-02-03
 2       | Mary | Lee     | PASS   | 2012-02-04
 ...     | ...  | ...     | ...    | ...
 3       | John | Doe     | FAIL   | 2012-03-01
 3       | Ryan | Smith   | FAIL   | 2012-03-02
 3       | Ann  | Evans   | PASS   | 2012-03-03
 3       | Mary | Lee     | FAIL   | 2012-03-04 <--
Run Code Online (Sandbox Code Playgroud)

请注意,exam_no并且date不一定与我选择的示例所期望的相关.

现在,我需要做的查询如下:

  • 从最新的考试(exam_no= 3)中找到所有失败的学生(John Doe,Ryan SmithMary Lee).
  • 对于这些学生中的每一个,找到一批连续失败的考试中的第一个的日期.另一种说法是:对于这些学生中的每一个,找到他们上次通过考试后第一次失败考试的日期.(看看表中的箭头).

结果表应该是这样的:

 name | surname | date_since_failing
------+---------+--------------------
 John | Doe     | 2012-02-01
 Ryan | Smith   | 2012-01-02
 Mary | Lee     | 2012-03-04
Run Code Online (Sandbox Code Playgroud)

我该如何执行这样的查询?

感谢您的时间.

egg*_*yal 4

您可以利用这样一个事实:如果某人通过了最近的考试,那么自最近通过以来他们没有未通过任何考试:因此问题简化为发现自最近通过以来第一次考试失败:

SELECT   name, surname, MIN(date) date_since_fail
FROM     results NATURAL LEFT JOIN (
  SELECT   name, surname, MAX(date) lastpass
  FROM     results
  WHERE    result = 'PASS'
  GROUP BY name, surname
) t
WHERE    result = 'FAIL' AND date > IFNULL(lastpass,0)
GROUP BY name, surname
Run Code Online (Sandbox Code Playgroud)

在sqlfiddle上查看它。