Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.
Umfragen und Quiz mit mehreren Fragen auszuwerten ist manchmal gar nicht so einfach. Im folgenden Beispiel werden eine Reihe von Fragen und deren Antworten geprüft. Nur die Teilnehmer, die alle Fragen richtig beantwortet haben, sollen aufgelistet werden.
* MySQL 5.1.30
* IBM DB2 9.1
Die Datenbank-Tabellen hierfür sehen wie folgt aus:
/**
* Teilnehmer der Umfrage bzw. des Quiz
*/
CREATE TABLE teilnehmer (
t_id INT NOT NULL,
name VARCHAR(100) NOT NULL,
PRIMARY KEY (t_id)
);
/**
* Die Fragen und die richtige Antwort
*/
CREATE TABLE fragen (
f_id INT NOT NULL,
frage VARCHAR(200) NOT NULL,
richtig INT NOT NULL,
PRIMARY KEY (f_id)
);
/**
* Die Antworten der Teilnehmer
*/
CREATE TABLE teilnehmer_antwort (
ta_id INT NOT NULL,
t_id INT NOT NULL,
f_id INT NOT NULL,
antwort INT NOT NULL,
PRIMARY KEY (ta_id),
CONSTRAINT fk_teilnehmer
FOREIGN KEY (t_id)
REFERENCES teilnehmer (t_id),
CONSTRAINT fk_fragen
FOREIGN KEY (f_id)
REFERENCES fragen (f_id)
);
Ein Teilnehmer muss sich registrieren (Tabelle teilnehmer) und kann dann die Fragen (per ankreuzen) beantworten. Die Antworten werden in der Tabelle teilnehmer_antwort gesammelt. Zu jeder Frage gibt es nur eine korrekte Antwort. Die Fragen und die richtigen Antworten (Nr) sind in der Tabelle fragen gespeichert. Die Tabelle mit allen Antworten des Quiz (also die richtigen und die falschen, unter denen der Teilnehmer wählen kann) wird für die Auswertung nicht benötigt.
Für das nachfolgende Beispiel legen wir uns ein paar Testdaten an. Es werden drei Teilnehmer, drei Fragen, sowie die neun Antworten der Teilnehmer in die Datenbank eingelesen.
/**
* Einfügen der drei Teilehmer
*/
INSERT INTO teilnehmer (t_id, name ) VALUES
(1, 'Teilnehmer-1'),
(2, 'Teilnehmer-2'),
(3, 'Teilnehmer-3');
/**
* Einfügen der drei Fragen
*/
INSERT INTO fragen (f_id, frage, richtig) VALUES
(1, 'Das ist die Frage 1', 1),
(2, 'Das ist die Frage 2', 2),
(3, 'Das ist die Frage 3', 2);
/**
* Einfügen der neun Antworten der Teilnehmer
*/
INSERT INTO teilnehmer_antwort (ta_id, t_id, f_id, antwort) VALUES
(1, 1, 1, 1),
(2, 1, 2, 2),
(3, 1, 3, 2),
(4, 2, 1, 1),
(5, 2, 2, 2),
(6, 2, 3, 4),
(7, 3, 1, 2),
(8, 3, 2, 2),
(9, 3, 3, 3);
Nun machen wir uns daran auszuwerten, welcher Teilnehmer alle Fragen korrekt beantwortet hat. Die SQL-Abfrage hierfür sieht so aus:
/**
* Die Teilnehmer ermitteln, die alle Fragen korrekt beantwortet haben
*/
SELECT t.name
FROM teilnehmer t
JOIN (SELECT t_id, COUNT(*) AS anzahl
FROM teilnehmer_antwort ta
JOIN fragen f
ON ta.f_id = f.f_id
AND ta.antwort = f.richtig
GROUP BY t_id
) richtig
ON richtig.t_id = t.t_id
JOIN ( SELECT COUNT(*) AS anzahl FROM fragen) fragen
ON richtig.anzahl = fragen.anzahl;
+--------------+
| name |
+--------------+
| Teilnehmer-1 |
+--------------+
1 row in set (0.00 sec)
Der etwas komplexe Query ermittelt in mehreren Teilschritten das gewünschte Ergebnis. Der erste Sub-Select richtig liefert die Anzahl der richtigen Antworten pro Teilnehmer. Der zweite Sub-Select fragen zählt die Anzahl der notwendigen korrekten Antworten für dieses Quiz. Wenn jetzt diese beiden Werte richtig.anzahl = fragen.anzahl übereinstimmen, hat der Teilnehmer die richtige Menge an korrekten Antworten angekreuzt und wird als Ergebnis der Abfrage ausgegeben. In unserem Beispiel trifft dies auf den Teilnehmer Teilnehmer-1 zu.