2017-02-24 4 views
0

Ich habe eine Datenbank, die Prüfungsaufzeichnungen speichert: tbl_exams speichert die ID und den Namen der Prüfungen - es gibt nur 9 Prüfungen und so nur 9 Datensätze in dieser Tabelle als Prüfungen sind festgelegt und ändern sich nicht. tbl_exam_details speichert alle Details für einen Prüfungseintrag und enthält die entsprechende ID aus tbl_exams - dafür gibt es eine Fremdschlüsseleinschränkung. Was ich versuche, ist eine Abfrage erstellen, die nur Zeilen zurückgibt, wenn alle 9 Prüfungen von einem bestimmten Studenten genommen wurden und das pass_or_fail Feld ist '1' - ich verwende tinyint(1), um 1 zu speichern, die pass ist, oder 0, die fehlschlägt). Dies ist im Wesentlichen zu überprüfen, ob alle 9 Prüfungen bestanden wurden.MySQL - Zeilen nur zurückgeben, wenn alle Werte in der WHERE-Klausel vorhanden sind

Das ist, was ich bisher habe, ist es jedoch Reihen, auch wenn der Student Rückkehr nur eine oder zwei Prüfungen abgeschlossen hat:

SELECT tbl_exam_details.student_id, exam_name, exam_date, pass_or_fail FROM tbl_exam_details 
INNER JOIN tbl_exams ON tbl_exams.exam_id = tbl_exam_details.exam_id 
WHERE student_id = 1 AND pass_or_fail = 1 
AND tbl_exam_details.exam_id IN (1, 2, 3, 4, 5, 6, 7, 8, 9) 
ORDER BY exam_details_id 

Was ich brauche, ist für die Abfrage nur die Zeilen zurück, sobald alle 9 Prüfungen wurden bestanden. Wenn ein Schüler also 8 Prüfungen bestanden hat, sollte die Abfrage 0 Zeilen zurückgeben. Wenn mir jemand helfen könnte, wäre ich sehr dankbar.

+1

Können Sie Ihre Frage bearbeiten und Beispieldaten und gewünschte Ergebnisse bereitstellen? –

+0

Sie könnten eine 'all_exams'-Spalte erstellen, die automatisch aktualisiert wird, wenn die Tabelle geändert wird. all_exams = 1 wenn alle exam_id gesetzt sind, sonst 0. – nncho

Antwort

2
SELECT ted.student_id, 
     exam_name, 
     exam_date, 
     pass_or_fail 
FROM tbl_exam_details ted 
INNER JOIN tbl_exams 
    ON tbl_exams.exam_id = ted.exam_id 
WHERE student_id = 1 
    AND (SELECT COUNT(*) 
     FROM tbl_exam_details ted2 
     WHERE ted2.pass_or_fail = 1 
     AND ted2.student_id = ted.student_id 
    ) = 9 -- mean this student pass 9 exams 
ORDER BY exam_details_id 
+0

Warum nicht' WHERE tbl_exam_details.pass_or_fail = 1 UND tbl_exam_details.student_id = ted.student_id'? – JohnHC

+0

@JohnHC Ja, ich habe das behoben. Danke –

+0

Markieren Sie dies als richtig, da es auch die zusätzlichen Felder anzeigt, die ich brauchte. – sinesine

0

Sie für eine vollständige Liste GROUP_CONCAT kann ...

select x1.* 
from 
(
select t1.*, group_concat(distinct exam_id order by exam_id separator '|') as x_list 
from tbl_exam_details t1 
where pass_or_fail = 1 
group by student_id 
) x1 
where x_list = '1|2|3|4|5|6|7|8|9' 
+1

Sie brauchen wahrscheinlich hinzufügen Reihenfolge von auf der "concat"? –

+0

Dies erzeugt einen Fehler: '# 1248 - Jede abgeleitete Tabelle muss ihren eigenen Alias ​​haben ' – sinesine

+0

@sinesine Leicht zu beheben ... – JohnHC

1

Ist das, was Sie wollen?

SELECT ed.student_id 
FROM tbl_exam_details ed 
WHERE ed.student_id = 1 AND ed.pass_or_fail = 1 AND 
     ed.exam_id IN (1, 2, 3, 4, 5, 6, 7, 8, 9) 
GROUP BY ed.student_id 
HAVING COUNT(*) = 9; -- or maybe COUNT(DISTINCT exam_id) = 9 

Dies gibt die Schüler-IDs zurück, die die 9 Prüfungen bestanden haben. Es enthält keine anderen Informationen.

+0

Das ist es genau, danke! Wird als richtig akzeptieren wenn es mich lässt. Was meintest du mit "oder vielleicht COUNT (DISTINCT exam_id) = 9" nur aus Neugier? – sinesine

+0

@sinesine Falls eine Prüfung mehrere Male "bestanden" werden kann. Aber in diesem Fall können Sie die Prüfung nur einmal bestehen, also sollte kein Problem sein. –

+0

@Juan Carlos Oropeza Ich sehe, danke für die Hilfe. – sinesine

Verwandte Themen