Mahlzeit,
ich schraube gerade an einer Datenbankabfrage für eine Umfragesoftware und könnte etwas Hilfe beim Weiterentwickeln meines bisherigen Ergebnisses gebrauchen. Folgende Tabellen und Felder sind relevant:
questions:
- qid: Primary Key
- sid: ordnet Fragen einer Umfrage zu
- aid: ordnet Fragen einen Antworttyp zu
- question: enthält den Fragetext
answer_types:
- aid: Primary Key
- sid: ordnet Antworttyp einer Umfrage zu (jede Umfrage definiert sich ihre eigenen Typen)
- type: Antworttyp (Textfeld, Multiply Choice, ...)
answer_values:
- avid: Primary Key
- aid: ordnet einem Antworttypen die Antwortmöglichkeiten zu
- value: Antworttext ("Ja", "Nein", "Zu viel", ...)
results: (vom Benutzer ausgewählte Antworten in Multiple Choice u.ä.)
- rid: Primary Key
- qid: ordnet ein Ergebnis einer Frage zu
- sid: ordnet ein Ergebnis einer Umfrage zu
- avid: ordnet dem Ergebnis einen Antworttyp zu
results_text: (vom Benutzer frei eingegebene Texte)
- wie results, nur mit einem Feld answer für den Texteintrag anstatt der avid
Wie man sieht, ist diese Struktur nicht komplett normalisiert -- das DB-Design ist aber vorgegeben. Ich hantiere hier übrigens mit MySQL 5.
Nun möchte ich aus Datensätzen dieser DB die Auswertung einer Umfrage erstellen. Gehen wir mal davon aus, daß es nur zwei Fragetypen gibt:
(A) Multiple Choice (Tabelle results) und
(B) Textfelder, die der Benutzer nach Belieben ausfüllen kann (Tabelle results_text).
Für A interessieren mich in der Auswertung die verfügbaren Optionen mit Text (answer_values.value) und wie häufig jede dieser Optionen insgesamt ausgewählt wurde.
Für B möchte ich einfach eine Auflistung der Texte haben (results_text.answer). Inhaltliche Doppelungen werden nicht berücksichtigt, d.h. wenn zwei Leute den gleichen Text geschrieben haben, dürfen ruhig beide Texte in der Auswertung auftauchen.
Das ist erstmal nicht so kompliziert und funktioniert im Einsatz auch schon. Allerdings werden u.A. die Antworten auf jeweils eine Frage einzeln von der DB erfragt -- nicht besonders schön, besonders bei umfangreichen Umfragen. Das muß sich doch auch in einem Rutsch erledigen lassen, dachte ich mir und widmete mich erstmal Teil A. Das sah dann so aus:
SELECT
q.qid, q.question, q.aid,
a.type,
av.avid, av.value,
COUNT(av.avid)
FROM
questions q,
answer_types a,
answer_values av,
results r
WHERE
-- nur die Fragen einer bestimmten Umfrage
q.sid = 32
-- nur die Antworttypen der vorher gefilterten Fragen
AND a.aid = q.aid
-- nur die Antwortwerte der vorher gefilterten Antworttypen
AND av.aid = a.aid
-- nur die ausgewählten Antworten (Ergebnisse) auf vorher
-- gefilterte Fragen und Antwortwerte
AND r.qid = q.qid
AND r.avid = av.avid
GROUP BY
av.avid, q.qid
Das läßt sich natürlich auch mit JOINs schreiben. Ich wollte beim Konstruieren nur erstmal den Überblick behalten, und das fiel mir leichter mit den Kreuzprodukt mehrere Tabellen, welches jeweils durch WHERE gefiltert wird ...
Beim Ergebnis gibt es allerdings ein Problem: Durch die Gruppierung gehen Antworttypen verloren, die kein einziges Mal ausgewählt wurden (wofür COUNT(av.avid) also 0 liefern würde). Krieg ich doch bloß wieder durch JOINs mit hinein?
Dann fehlt natürlich noch Teil B der Auswertung, und hier steh ich nun wirklich auf dem Schlauch. Das Endergebnis muß ja etwas Gemischtes sein, Weil sich A und B in der Art und Weise, wie sie in der DB abgelegt werden, ziemlich unterscheiden. Ich stelle mir das etwa so vor (mc = Multiple Choice, txt = freier Texteintrag):
+-----+------+---------------+------------------+------+
| qid | type | question | value | cnt |
+-----+------+---------------+------------------+------+
| 1 | mc | Was gibt's? | Nichts | 120 |
| 1 | mc | Was gibt's? | Ärger | 50 |
| 2 | txt | Und sonst so? | Muß ja. | NULL |
| 2 | txt | Und sonst so? | Gut. Und selber? | NULL |
| 2 | txt | Und sonst so? | Ooch, weiß nich. | NULL |
+-----+------+---------------+------------------+------+
Wie krieg ich meinen bisherigen Ansatz noch erweitert, um results_text in dieser Form mit ins Ergebnis einfließen zu lassen? (Oder ist es gar keine so gute Idee, diese beiden unterschiedlichen Ergebnistypen auf Teufel komm raus in dieser Form miteinander verheiraten zu wollen?)
Für jeden hilfreichen Tip dankbar,
Alex