2015-07-05 11 views
5

Sto cercando di capire quale lingua un utente risponda di più e restituire tramite user_id, il numero language_id risponda nella maggior parte e quante volte hanno delle risposte.Utilizzo di MAX() e COUNT() nella stessa query

Ho cominciato SELECT ing un tavolo/sub-tavolo che restituisce questi risultati:

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 

Questa tabella restituisce il user_id, il language_id, e quante volte che language_id ha ricevuto risposta da parte dell'utente. Ho usato questa query per farlo:

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 

La struttura della tabella è:

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

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

I translations tabella contiene tutte le traduzioni richieste, e le translation_results tabella contiene le risposte a quelle traduzioni e il rispettivo user_id .

Quindi, per riassumere la tavola e per ottenere l'user_id, la maggior parte ha risposto language_id, e quante volte hanno risposto in quel language_id, ho usato:

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 

Ma questo non comprimere la tabella in la struttura desiderata e restituisce invece:

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 

so che è influenzato dal gruppo dal di two clauses, ma poi se solo gruppo da user_id e non includono to_language_id nelle mie colonne selezionate, non posso sapere quale respectiv e language_id è la più risposta. Ho anche provato sotto-query e alcuni join, ma trovo che ho costantemente bisogno di usare MAX(t1.answers) a prescindere dalle colonne selezionate e quindi distrugge le mie speranze di agguantare correttamente il group by. Come posso comprimere correttamente la query invece di avere group by trovare tutte le combinazioni MAX() univoche di user_id e to_language_id?

+0

Hi è possibile creare [SQL Fiddle] (http://sqlfiddle.com/) con alcuni dati e aggiungi alla domanda l'output desiderato? tnx –

risposta

1

Per ottenere risultati:

il user_id, la loro più risposto language_id, e quante volte risposto in quel language_id

è possibile utilizzare le variabili:

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 

Ci è una limitazione tuttavia nella query precedente: se ci sono più di uno language_id condividendo lo stesso m un numero massimo di risposte per uno user_id, quindi verrà restituito solo uno.

Demo here

Un modo alternativo, è quello di utilizzare si esegue una query il doppio di una tabella derivata:

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 

Questa query non ha la limitazione della query precedente, ma è probabile che sia meno efficiente rispetto al precedente.

Demo here

+0

Risposta sorprendente, grande demo e buona spiegazione. Grazie –

0

Se comprensione passa alla tua domanda, è necessario definire una tabella temporanea o derivato, con il risultato della sottoquery, lascia chiamata è sub_selected, allora si dovrebbe fare:

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) 
Problemi correlati