2012-07-04 13 views
8

Muszę wykonać stosunkowo łatwe do wytłumaczenia, ale (biorąc pod uwagę moje nieco ograniczone umiejętności) trudne do napisania zapytanie SQL.Tricky zapytanie SQL z kolejnymi wartościami

Załóżmy, że mamy tabelę podobny do tego:

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

pamiętać, że exam_no i date niekoniecznie są związane, jak można by oczekiwać od rodzaju przykład wybrałem.

Teraz, zapytanie, że muszę zrobić to w następujący sposób:

  • Od najnowszej egzaminu (exam_no = 3) Znajdź wszystkie uczniów, które nie powiodło się (John Doe, Ryan Smith i Mary Lee).
  • Dla każdego z tych studentów znajdź datę pierwszej z serii kolejnych egzaminów nieudanych. Innym sposobem na to byłoby: dla każdego z tych studentów znaleźć datę pierwszego nieudanego egzaminu, który pojawia się po ostatnim zdanym egzaminie. (Spójrz na strzałki w tabeli).

Powstały tabela powinna być mniej więcej tak:

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

Jak mogę wykonać takie zapytanie?

Dziękuję za poświęcony czas.

+0

Inni czytelnicy: zauważ, że oznaczył go jako 'MySQL' –

+0

Pomyśl, że możesz dołączyć do tego samego stołu na wyniku = 'FAIL' i wybrać z niego ten, który ma najwyższą datę. Co próbujesz? – Jocke

+0

Co masz na myśli przez "* ostatni egzamin *"? Egzamin, który ma najnowszą datę? – eggyal

Odpowiedz

4

można skorzystać z faktu, że jeśli ktoś przeszedł najnowsze egzamin, wtedy nie udało żadnych egzaminów od czasu ich ostatniej przełęczy przeto problem sprowadza się do znalezienia pierwszy egzamin nie powiodło się, ponieważ ostatnim przejściu:

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 

Zobacz na sqlfiddle.

+0

To jest dokładnie to. Nie mogę uwierzyć, jak lapidarne i proste jest zrozumienie. Udało mi się go dostosować do mojego prawdziwego problemu przy minimalnym wysiłku. Dziękuję bardzo. – Gabriel

0

należy używać podkwerenda że pobieraniu ostatni egzamin, somthing jak:

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 
0

To wystarczy:

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 
0

Warunkiem prosicie jest dobra na nic nie można zrobić bez niego. Oto działający przykład.

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 

ta produkuje ten wynik

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

To nie jest wynik, którego szukam. Daty powinny być tymi, które pojawiają się w tabeli wyników w moim pytaniu. To, czego szukam, to data pierwszego nieudanego egzaminu w najnowszej partii kolejnych egzaminów nieudanych dla każdego z tych studentów. – Gabriel

+0

Nie, przepraszam. Wyniki, których szukam, są dokładnie tymi, które pierwotnie napisałem w moim pytaniu.Nie edytuj mojego pytania, aby dopasować je do wyników, to naprawdę brak szacunku. – Gabriel