2015-07-05 4 views
5

Ich versuche herauszufinden, welche Sprache ein Benutzer am meisten antwortet, und geben Sie user_id, die language_id antworten sie am häufigsten und wie oft sie Antworten haben.Mit MAX() und COUNT() in der gleichen Abfrage

Ich begann SELECT einen Tisch/Untertabelle ing, die diese Ergebnisse zurückgibt:

Table: `sub-selected` 
`user_id` `language_id` `answers` 
    1    1    1 
    2    1    1 
    1    2    5 
    2    2    2 
    1    4    3 
    1    5    1 

Diese Tabelle gibt die user_id, die language_id, und wie oft, dass language_id vom Benutzer beantwortet. Ich habe diese Abfrage um es zu bekommen:

SELECT t1.user_id, t2.to_language_id, COUNT(t2.to_language_id) as answers 
FROM translation_results as t1 
LEFT JOIN translations as t2 
ON t2.translation_id = t1.translation_id 
GROUP BY t2.to_language_id, t1.user_id 

Die Tabellenstruktur ist:

Table: `translations` 
`translation_id` `from_phrase_id` `to_language_id` 

Table: `translation_results` 
`translation_id` `result_id` PRI-AI `user_id` 

Die translations Tabelle speichert alle Übersetzungen angefordert und die translation_results Tabelle speichert die Antworten auf diese Übersetzungen und die jeweiligen user_id .

Also, um die Tabelle zu summieren und die user_id zu bekommen, ihre meisten beantwortet language_id, und wie oft sie in dieser language_id beantwortet, habe ich:

SELECT t1.user_id, t1.to_language_id, MAX(t1.answers) 
FROM (
    //The sub-table 
    SELECT t1.user_id, t2.to_language_id, COUNT(t2.to_language_id) as answers 
    FROM translation_results as t1 
    LEFT JOIN translations as t2 
    ON t2.translation_id = t1.translation_id 
    GROUP BY t2.to_language_id, t1.user_id 
) as t1 
GROUP BY t1.user_id, t1.to_language_id 

Aber nicht kollabiert die Tabelle in die gewünschte Struktur und stattdessen zurückgibt:

Table: `sub-selected` 
`user_id` `language_id` `answers` 
    1    1    1 
    1    2    5 
    1    4    3 
    1    5    1 
    2    1    1 
    2    2    2 

ich weiß es von der Gruppe von two clauses betroffen ist, aber dann, wenn ich nur Gruppe von user_id und umfassen nicht to_language_id in meiner ausgewählten Spalten, kann ich nicht wissen, welche respectiv e language_id wird am häufigsten beantwortet. Ich habe auch versucht, Unterabfragen und ein paar Joins, aber ich finde, ich brauche ständig MAX(t1.answers) unabhängig in den ausgewählten Spalten und zerstört damit meine Hoffnungen, die group by korrekt zu kollabieren. Wie kann ich die Abfrage korrekt ausblenden, anstatt group by alle eindeutigen MAX() Kombinationen von user_id und to_language_id zu finden?

+0

Hallo können Sie erstellen [SQL Fiddle] (http://sqlfiddle.com/) mit einigen Daten und fügen Sie Ihre Frage gewünschte Ausgabe? tnx –

Antwort

1

Um:

die user_id, ihre meisten language_id beantwortet, und wie oft sie in diesem language_id beantwortet

Sie Variablen verwenden können:

SELECT user_id, language_id, answers 
FROM (
    SELECT user_id, language_id, answers, 
     @rn:= IF(@uid = user_id, 
        IF(@uid:=user_id, @rn:[email protected]+1, @rn:[email protected]+1), 
        IF(@uid:=user_id, @rn:=1, @rn:=1)) AS rn 
    FROM (SELECT t1.user_id, t2.to_language_id AS language_id, 
       COUNT(t2.to_language_id) as answers  
     FROM translation_results as t1 
     LEFT JOIN translations as t2 
      ON t2.translation_id = t1.translation_id 
     GROUP BY t2.to_language_id, t1.user_id 
     ) t 
    CROSS JOIN (SELECT @rn:=0, @uid:=0) AS vars 
    ORDER BY user_id, answers DESC 
) s 
WHERE s.rn = 1 

Es ist jedoch eine Einschränkung in der obigen Abfrage: Wenn es mehr als eine language_id teilen die gleichen m Maximale Anzahl der Antworten für eine user_id, dann wird nur eine zurückgegeben.

Demo here

Eine alternative Möglichkeit ist doppelt so abgeleitete Tabelle abfragen, um zu verwenden:

SELECT t1.user_id, language_id, t1.answers 
FROM (SELECT t1.user_id, t2.to_language_id AS language_id, 
      COUNT(t2.to_language_id) as answers 
     FROM translation_results as t1 
     LEFT JOIN translations as t2 
     ON t2.translation_id = t1.translation_id 
     GROUP BY t2.to_language_id, t1.user_id) t1 
INNER JOIN (  
    SELECT user_id, MAX(answers) AS answers 
    FROM (SELECT t1.user_id, t2.to_language_id, 
       COUNT(t2.to_language_id) as answers 
     FROM translation_results as t1 
     LEFT JOIN translations as t2 
      ON t2.translation_id = t1.translation_id 
     GROUP BY t2.to_language_id, t1.user_id 
     ) t 
    GROUP BY user_id) t2 
ON t1.user_id = t2.user_id AND t1.answers = t2.answers 

Diese Abfrage nicht die Begrenzung der vorherigen Abfrage hat, aber wahrscheinlich weniger effizient sein verglichen mit dem vorherigen.

Demo here

+0

Erstaunliche Antwort, tolle Demo und gute Erklärung. Vielen Dank –

0

Wenn ich Ihre Frage undestood, sollten Sie eine temporäre oder eine abgeleitete Tabelle mit dem Ergebnis der Unterabfrage definieren, lässt Anruf sub_selected ist, dann sollten Sie tun:

SELECT t1.user_id, t1.to_language_id, answers 
FROM sub_selected as t1 
WHERE t1.answers = 
    (SELECT MAX(answers) 
    FROM sub_selected t2 
    WHERE t1.user_id = t2.user_id and t1.to_language_id = t2.language_id)