简体   繁体   English

棘手的SQL查询涉及连续值

[英]Tricky SQL query involving consecutive values

I need to perform a relatively easy to explain but (given my somewhat limited skills) hard to write SQL query. 我需要执行相对容易解释的操作,但是(鉴于我的技能有限)很难编写SQL查询。

Assume we have a table similar to this one: 假设我们有一张与此表类似的表:

 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 <--

Note that exam_no and date aren't necessarily related as one might expect from the kind of example I chose. 请注意, exam_nodate不一定像我选择的示例中所期望的那样相关。

Now, the query that I need to do is as follows: 现在,我需要执行的查询如下:

  • From the latest exam ( exam_no = 3) find all the students that have failed ( John Doe , Ryan Smith and Mary Lee ). 从最新的考试( exam_no = 3)中查找所有失败的学生( John DoeRyan SmithMary Lee )。
  • For each of these students find the date of the first of the batch of consecutively failing exams. 为这些学生中的每一个找到连续失败的第一批考试的日期。 Another way to put it would be: for each of these students find the date of the first failing exam that comes after their last passing exam. 另一种表达方式是:为每位学生找到在上一次及格考试之后的第一次不及格考试的日期。 (Look at the arrows in the table). (查看表中的箭头)。

The resulting table should be something like this: 结果表应该是这样的:

 name | surname | date_since_failing
------+---------+--------------------
 John | Doe     | 2012-02-01
 Ryan | Smith   | 2012-01-02
 Mary | Lee     | 2012-03-04

How can I perform such a query? 如何执行这样的查询?

Thank you for your time. 感谢您的时间。

You can take advantage of the fact that if someone passed the most recent exam, then they have not failed any exams since their most recent pass: therefore the problem reduces to finding the first exam failed since the most recent pass: 您可以利用以下事实:如果某人通过了最近的考试,那么自从最近通过考试以来,他们还没有通过任何考试:因此,问题可以归结为找到自最近通过考试以来的第一次考试失败:

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

See it on sqlfiddle . sqlfiddle上看到它。

I should use a subquery that fetch last passed exam, somthing like: 我应该使用可以获取最近通过的考试的子查询,例如:

SET @query_exam_no = 3;
SELECT
 name,
 surname,
 MIN(IF(date > last_passed_exam, date, NULL)) AS date_failing_since
FROM
 exam_results
 LEFT JOIN (
  SELECT
   name,
   surname, 
   MAX(date) AS last_passed_exam 
  FROM exam_results 
  WHERE result = 'PASS' 
  GROUP BY name, surname
 ) AS last_passed_exams USING (name, surname)
HAVING
 MAX(IF(exam_no = @query_exam_no, result, NULL)) = 'FAIL'
GROUP BY name, surname

This is enough: 这就够了:

select t.name,
       t.surname,
       t.date as 'date_since_failing'
from tablename t
inner join
(
    select name,
           surname,
           max(exam_no) as exam_no
    from tablename
    group by name, surname
    having min(result) = 'FAIL'
) aux on t.name = aux.name and t.surname = aux.surname and t.exam_no = aux.exam_no

The condition you are asking for is good for nothing you can do it without it. 您所要求的条件无济于事,没有它您将无能为力。 Here is the working example. 这是工作示例。

select
  e.name,
  e.sur_name,
  min(e.date) as `LastFailed`
from exams as e
where e.result = 'Fail'
group by e.name
    order by e.name 

This produces this result 这产生了这个结果

name            sur_name    LastFailed
Ann         Evans       2012-02-03
John        Doe         2012-02-01
Mary        Lee         2012-01-04
Ryan        Smith       2012-01-02

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

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