2 Tabellen Verküpfen

time-master

Erfahrenes Mitglied
Moin

Ich habe zwei Tabellen (questions und answer) und will mit einem Sql-Query alle Fragen auslesen und dazu die Antwort eines Users..

Code:
SELECT q.*, a.Answer 
FROM questions AS q
LEFT OUTER JOIN answer AS a
ON q.QuestionId = a.QuestionId
WHERE a.UserId = '1'

So funktioniert es schon fast, allerdings bekomme ich hierbei nur die Fragen zurück, auf die schon geantwortet wurde!
Ich will aber immer alle Fragen bekommen und wenn vorhanden, die Antwort dazu!
Das ich immer nur die Fragen bekomme, die auch eine Antwort besitzen, liegt an dieser Bedingung "q.QuestionId = a.QuestionId", aber wie kann ich das Abändern, damit es funktioniert?

Müsste eigentlich recht einfach sein, trotzdem komme ich nicht auf die richtige Lösung und konnte auch nichts im Netz finden.
 
Hallo,

schreib mal anstelle

SQL:
...WHERE a.userId = 1

das hier (denke das meinst du):

SQL:
... WHERE q.userId=1

Erklärung:

Durch dein "a.userId = 1" machst du aus deinem LEFT OUTER JOIN effektiv wieder einen INNER JOIN. Damit siehst du den von dir beschriebenen Effekt, dass du nur die Fragen siehst, auf die geantwortet wurde (und zwar vom User mit der user_id 1).

Die andere Statement Klausel "ON (q.QuestionId = a.QuestionId)" hat nichts damit zu tun, weil es ja den Join (LEFT OUTER JOIN) näher beschreibt und der gerade besagt, dass es egal sein soll, ob Antworten zu einer Frage vorhanden sind.

Markus
 
Zuletzt bearbeitet:
Ne..
Ich meine schon

Code:
a.userId = 1

Es ist so, das meine Tabelle questions keinen user hat. Die Tabelle hat nur eine Auflistung von ca. 20 Fragen und in der Tabelle answer sollen die Antworten gespeichert werden.
Die Tabelle Answer hat eine Verknüpfung zur Tabelle question. Jede Frage kann n Antworten haben, aber höchstens eine Antwort pro User.
 
Hallo,

ok wenn es kein Fehler war, sondern Absicht ist, schreib dein Statement so: :)
(Du fügst es effektiv zur JOIN-Bedingung hinzu)

SQL:
SELECT q.*, a.Answer 
  FROM questions AS q
  LEFT OUTER JOIN answer AS a
  ON ( q.QuestionId = a.QuestionId AND a.UserId = '1')

Markus
 
Damit löse ich doch aber nicht mein Problem..

Ich möchte mit einer Sql-Abfrage eine Liste aller Fragen ( ca. 20 Fragen ) erhalten. Und wenn es schon eine Antwort des angegebenen Users dazu gibt möchte ich diese in einer extra Spalte hinzufügen. Ansonsten soll die Zelle leer bleiben.
 
Hallo,

genau das macht das Statement doch.
Du erhältst in deiner Abfrage in der entsprechenden Spalte für die Antwort die Antwort des Users mit der ID oder eben NULL, bedingt durch das LEFT OUTER JOIN.

Verstehe dein Problem nun nicht mehr, sorry. Habs grad nochmal ausprobiert. Bei mir gehts ohne jedes Problem..

Markus

Edit: Hab dir nochmal die Schritte gepostet, mit denen ich das ganze grad nochmal simuliert hab:

SQL:
CREATE TABLE questions (
  id int(2) ,
  beschreibung varchar(100)
);

CREATE TABLE answers (
  question_id int(2),
  user_id int(2),
  beschreibung varchar(100)
);

-- Einfügen von Fragen
INSERT INTO questions VALUES (1,'Frage 1');
INSERT INTO questions VALUES (2,'Frage 2');
INSERT INTO questions VALUES (3,'Frage 3');
INSERT INTO questions VALUES (4,'Frage 4');

-- Einfügen der Beispiel-Antworten
INSERT INTO answers VALUES (1,1,'Antwort von User 1 auf Frage 1');
INSERT INTO answers VALUES (1,2,'Antwort von User 2 auf Frage 1');
INSERT INTO answers VALUES (2,1,'Antwort von User 1 auf Frage 2');

Jetzt führe ich folgendes Statement aus:

SQL:
select q.*, a.beschreibung as antwort 
  from questions q 
  LEFT OUTER JOIN answers a 
  ON (q.id = a.question_id and a.user_id=1)

und ich bekomme:
Code:
1, 'Wie gehts denn das (Frage 1)', 'Antwort von User 1 auf Frage 1'
2, 'Wie gehts denn das (Frage 2)', 'Antwort von User 1 auf Frage 2'
3, 'Wie gehts denn das (Frage 3)', ''
4, 'Wie gehts denn das (Frage 4)', ''

also alle Fragen inklusive der Antworten, die User 1 gegeben hat. Bei Frage 3 und 4 hat dieser User keine Antworten gegeben, also wird NULL (kein Wert) zurückgeben.

Für den zweiten User das gleiche:

SQL:
select q.*, a.beschreibung as antwort 
  from questions q 
  LEFT OUTER JOIN answers a 
  ON (q.id = a.question_id and a.user_id=2)

Als Ergebnis:

Code:
1, 'Wie gehts denn das (Frage 1)', 'Antwort von User 2 auf Frage 1'
2, 'Wie gehts denn das (Frage 2)', ''
3, 'Wie gehts denn das (Frage 3)', ''
4, 'Wie gehts denn das (Frage 4)', ''

Dieser User hat nur die erste Frage beantwortet, alle anderen Fragen komen natürlich trotzdem, aber ohne Antwort.

Falls ich total auf dem Schlauch stehen sollte, sag mir bitte Bescheid, aber ich dachte, es wäre genau das, was du suchst..

Markus
 
Zuletzt bearbeitet:
Ohh.. sry.. du hast recht..

Allerdings muss ich gestehen, das ich das Statement nicht wirklich verstehe. Warum muss ich die Bedingung in die ON Clause nehmen?
 
Hallo,

weil sie sonst nicht zu der OUTER-JOIN-Bedingung gehört und damit wie ein INNER JOIN wirkt. Das heisst sie schränkt die Datensätze tatsächlich nach dem OUTER JOIN wieder ein, auf diejenigen, die dem Benutzer gehören. Da dieser aber nicht auf jede Frage geantwortet haben wird, fallen hierbei alle anderen Fragen raus.

Markus
 
Zurück