简体   繁体   English

在同一查询中使用MAX()和COUNT()

[英]Using MAX() and COUNT() in the same query

I am trying to figure out what language a user answers in the most, and return by user_id , the language_id they answer in the most and how many times they have answers. 我试图找出用户最常回答的language_id ,并通过user_id返回,他们回答的language_id以及他们有多少次回答。

I began by SELECT ing a table/sub-table which returns these results: 我开始SELECT一个返回这些结果的表/子表:

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

This table returns the user_id , the language_id , and how many times that language_id has been answered by the user. 此表返回user_idlanguage_id以及用户已回答language_id次数。 I used this query to get it: 我用这个查询得到它:

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

The table structure is: 表结构是:

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

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

The translations table stores all the translations requested, and the translation_results table stores the answers to those translations and the respective user_id . translations表存储所请求的所有翻译,translation_results表存储这些翻译的答案和相应的user_id

So, to sum up the table and to get the user_id, their most answered language_id , and how many times they answered in that language_id , I used: 因此,为了总结表并获取user_id,他们最常回答的language_id ,以及他们在该language_id回答了多少次,我使用了:

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

But this does not collapse the table into the desired structure and instead returns: 但这不会将表格折叠成所需的结构,而是返回:

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

I know it is affected by the group by of two clauses , but then if I only group by user_id and do not include to_language_id in my selected columns, I can't know which respective language_id is the most answered. 我知道它受到two clauses的组的影响,但是如果我只按user_id分组并且在我选择的列中没有包含to_language_id,我不知道哪个相应的language_id是最常回答的。 I have also tried sub-queries and a few joins, but I find I constantly need to use MAX(t1.answers) regardless in the selected columns and thus destroys my hopes of collasping the group by correctly. 我也尝试了子查询和一些连接,但我发现无论在选定的列中我都经常需要使用MAX(t1.answers) ,从而破坏了我正确地整理group by希望。 How can I collapse the query correctly instead of having group by find all the unique MAX() combinations of user_id and to_language_id ? 如何group by找到user_idto_language_id所有唯一MAX()组合来正确折叠查询而不是to_language_id

To get: 要得到:

the user_id , their most answered language_id , and how many times they answered in that language_id user_id ,他们最常回答的language_id ,以及他们在该language_id中回答的次数

you can use variables: 你可以使用变量:

SELECT user_id, language_id, answers
FROM (
  SELECT user_id, language_id, answers,
         @rn:= IF(@uid = user_id,
                  IF(@uid:=user_id, @rn:=@rn+1, @rn:=@rn+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

There is a limitation however in the above query: if there are more than one language_id sharing the same maximum number of answers for a user_id , then only one will be returned. 但是在上述查询中存在一个限制:如果有多个language_id共享user_id的相同最大答案数,则只返回一个。

Demo here 在这里演示

An alternative way, is to use you query twice as a derived table: 另一种方法是使用两次查询作为派生表:

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 

This query does not have the limitation of the previous query, but is likely to be less efficient compared to the previous one. 此查询没有上一个查询的限制,但与前一个查询相比可能效率较低。

Demo here 在这里演示

If I undestood your question, you should define a temporary or derived table with the result of the subquery, lets call is sub_selected , then you should do: 如果我不理解您的问题,您应该使用子查询的结果定义临时表或派生表,让调用是sub_selected ,然后您应该:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM