2016-08-14 3 views
1

Ich habe eine Frage-und-Antwort-Website wie SO. Ich habe eine Tabelle wie folgt aus:Wie kann ich einen Beitrag und alle zugehörigen Beiträge auswählen?

// qanda 
+----+----------+----------------------+---------+------+ 
| id | title |  content  | related | type | 
+----+----------+----------------------+---------+------+ 
| 1 | a title | a content   | NULL | 0 | 
| 2 |   | a content   | 1  | 1 | 
| 3 | a title | a content   | NULL | 0 | 
| 4 |   | a content   | 1  | 1 | 
| 5 |   | a content   | 3  | 1 | 
+----+----------+----------------------+---------+------+ 
/* type column:  "0" means it is a question, "1" means it is a answer 
    related column: it contains the id number of its own question 
*/ 

Jetzt muss ich eine Frage auswählen und alle ihre eigenen Antworten auf der Grundlage einer id Nummer. (diese id Nummer kann entweder die ID einer Frage oder die ID einer Antwort sein).

Hier ist meine aktuelle Abfrage:

SELECT * FROM qanda WHERE id = :id OR related = :id 

Meine Abfrage funktioniert nur gut, wenn :id die ID eine Frage. (Ich meine, es funktioniert nicht richtig, wenn :id die ID einer Antwort sein).


Hier ist erwartetes Ergebnis:

assuming either :id = 1 or :id = 2 or :id = 4 
+----+----------+----------------------+---------+------+ 
| id | title |  content  | related | type | 
+----+----------+----------------------+---------+------+ 
| 1 | a title | a content   | NULL | 0 | 
| 2 |   | a content   | 1  | 1 | 
| 4 |   | a content   | 1  | 1 | 
+----+----------+----------------------+---------+------+ 

Wie ich bereits erwähnt, ich brauche diese drei Zeilen, wenn :id = 1 oder :id = 2 oder :id = 4 auszuwählen. Wie kann ich das machen?

+0

Es wäre sinnvoller, Ihr Schema in eine Frage- und Antworttabelle zu unterteilen und dann eine Fremdschlüsseleinschränkung für jede Antwort auf die übergeordnete Frage zu haben. Dieses aktuelle Design ist ein Rezept für eine Katastrophe – Alex

+0

@Alex Ich werde meine Datenbank-Design ändern * (Erstellen von zwei getrennten Tabelle für Fragen und Antworten) * wie das, was Sie in der nächsten Version meiner Website gesagt .. Derzeit muss ich das Problem lösen I ' m konfrontiert mit. –

+0

Wie viele Daten speichern Sie gerade, wenn Sie jetzt zu einem neuen Datenbankdesign migrieren können, würde ich es sehr empfehlen. Sie werden einige ernsthafte Performance-Engpässe treffen, wenn Sie mit diesem aktuellen Design skalieren, – Alex

Antwort

1

Die folgende Abfrage sollte funktionieren. Die Abfrage ist in 4 Teile geteilt, die zusammen unioniert sind. Beschreibung jeder Abfrage:

  1. Returns Frage, ob :id ist eine Frage
  2. Returns Antworten, wenn :id eine Frage
  3. Returns Frage, ob :id ist eine Antwort
  4. Returns Antworten, wenn :id ist eine Antwort

Abfrage:

select q.* 
    from quanda q 
where q.id = :id 
    and q.type = 0 
UNION ALL 
select a.* 
    from quanda a 
where a.related = :id 
UNION ALL 
select q.* 
    from quanda a 
    join quanda q 
    on q.id = a.related 
where a.id = :id 
    and a.type = 1 
UNION ALL 
select a2.* 
    from quanda a1 
    join quanda a2 
    on a2.related = a1.related 
where a1.id = :id 
    and a1.type = 1 
+0

Nur eine Frage, warum meine Frage zwei downvotes verdient hat? Was stimmt damit nicht? –

+2

Gebildete Vermutung: Ich vermute, einige downvoted, weil sie grundsätzlich mit Ihrem db-Design nicht einverstanden sind. Ich persönlich glaube nicht, dass dies ein stichhaltiger Grund für einen Downvote ist. Downvotes sollten für (wie es heißt, wenn Sie über das Downvote-Bild zeigen) Fragen sein, die einen Mangel an Anstrengung zeigen, nicht nützlich oder unklar sind. Obwohl nicht jeder dem zustimmen kann, was Sie zu tun versuchen, denke ich, dass Sie sich selbst klar erklärt haben, besonders wenn ich mit 90% der SQL-Fragen über SO vergleiche. – sstan

+2

Ich stimme @stan Kommentar zu, obwohl ich nicht mit Ihrem Datenbank-Design stimme Ich habe Ihren Beitrag tatsächlich upvote aufgrund der Zeit, die Sie offensichtlich in die Erstellung eingefügt. Es ist nicht von minderer Qualität, also glaube ich nicht, dass es verpasste Stimmen verdient hat! – Alex

Verwandte Themen