2017-05-26 2 views
0

Ich habe eine Tabelle wie folgt aus:Wie kann ich unbeantwortete Fragen auswählen?

CREATE TABLE `qanda` (
    `id` int(11) UNSIGNED NOT NULL, 
    `subject` varchar(150) COLLATE utf8_unicode_ci NOT NULL, 
    `body` text COLLATE utf8_unicode_ci NOT NULL, 
    `body_html` text COLLATE utf8_unicode_ci NOT NULL, 
    `related` int(11) UNSIGNED DEFAULT NULL, 
    `type` tinyint(1) NOT NULL, 
    `amount` decimal(11,0) DEFAULT NULL, 
    `closed` tinyint(1) UNSIGNED DEFAULT NULL, 
    `CloserId` varchar(500) COLLATE utf8_unicode_ci NOT NULL, 
    `AcceptedAnswer` tinyint(1) DEFAULT NULL, 
    `aadate` int(11) UNSIGNED DEFAULT NULL, 
    `category` varchar(20) COLLATE utf8_unicode_ci NOT NULL, 
    `keywords` varchar(150) COLLATE utf8_unicode_ci NOT NULL, 
    `visibility` tinyint(1) NOT NULL, 
    `author_id` int(11) UNSIGNED DEFAULT NULL, 
    `editor_id` int(11) UNSIGNED DEFAULT NULL, 
    `date_time` int(11) UNSIGNED NOT NULL, 
    `edited_at` int(11) UNSIGNED DEFAULT NULL, 
    `activated_at` int(11) UNSIGNED DEFAULT NULL, 
    `activated_story` enum('سوال شده','ویرایش شده','جواب داده شده','') COLLATE utf8_unicode_ci NOT NULL, 
    `activator_id` int(11) UNSIGNED DEFAULT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

Diese Tabelle speichert beide Fragen und Antworten. Hier ist meine aktuelle Abfrage, die eine Liste aller Fragen stellt und sortieren sie auf der Grundlage der Abstimmung:

SELECT *, (SELECT COALESCE(sum(vv.value),0) 
      FROM votes vv 
      WHERE qanda.id = vv.post_id) AS total_votes 
FROM qanda 
WHERE type = 0 -- "type=0" means questions 
ORDER BY total_votes DESC 
LIMIT :j,11; 

Jetzt brauche ich eine weitere Bedingung für die WHERE Klausel Fragen auszuschließen, die Antwort (en) haben. Ich denke, ich brauche eine . Aber ich weiß nicht, wie ich eine join über die where Klausel schreiben kann. Gibt es einen Vorschlag?

+2

Es ist sehr seltsam, beide Fragen und Antworten in einer Tabelle zu haben, da dies verschiedene Dinge sind. Sie sollten Ihr Datenmodell ändern und separate Tabellen erstellen. –

+1

Zu Ihrer Frage: Wie sehe ich, auf welche Frage sich eine Antwort bezieht? –

+0

Sie können eine "und nicht existiert (Ihre Abfrage)" in where-Klausel schreiben. wie du Frage ID mit dir hast. –

Antwort

1

Verwenden NOT IN IDs ausschließen, die beantwortet wurden:

SELECT *, (SELECT COALESCE(sum(vv.value),0) 
      FROM votes vv 
      WHERE qanda.id = vv.post_id) AS total_votes 
FROM qanda 
WHERE type = 0 
AND id NOT IN (SELECT related FROM quanda WHERE type <> 0) 
ORDER BY total_votes DESC 
LIMIT :j,11; 
+0

Oh .. schlau .. danke, upvote –

+0

Es ist eigentlich nichts schlaues daran. Wir verwenden '[NOT] IN' (oder' [NOT] EXISTS', wenn es komplizierter wird), wenn wir prüfen, ob Daten in einem Datensatz existieren (in Ihrem Fall: ob das Questien in den Antworten existiert). Wir verwenden nur Joins anstelle von kombinierten Ergebnissen. (Oder Anti-Joins, wie von Juan Carlos Oropeza gezeigt, wenn das DBMS Leistungsprobleme mit "NOT IN"/"NOT EXISTS" hat. MySQL war früher dafür bekannt, dass es bei IN-Ausdrücken schwach ist. Aber das gehört wohl der Vergangenheit an jetzt.) –

+0

Es gibt ein Problem .. in Ihrem Ansatz, wenn eine Frage mehrere Antworten hat, verursacht es mehrere Duplikate in 'NOT IN (...)' .. Habe ich Recht? –

1

Mit einem SELF JOIN, versuchen Sie mit jeder Antwort eine Frage zu entsprechen. Wenn Sie keine Übereinstimmung finden, erhalten Sie NULL, so erhalten Sie die Fragen ohne Antworten.

SELECT questions.* 
FROM qanda questions 
LEFT JOIN qanda answers 
    ON question.id = answers.related 
WHERE questions.type = 0 
    AND answers.id IS NULL 
+0

danke, upvote. –

Verwandte Themen