如何在MySQL中结合GROUP BY和MAX以获得具有字段最大值的完整记录?

时间:2018-07-18 11:18:29

标签: mysql

我有一个表'wordstyped',其中包含'idBook','guidUser','bookmarkLetter','letter'和'attemptWrong'。

idBook  guidUser  bookmarkLetter  letter  attemptWrong
------------------------------------------------------
1       1         100             a       2
1       1         100             a       3
1       1         101             b       6
2       2         101             b       2
2       2         101             b       3
2       2         152             d       7
3       3         153             e       2

我想选择所有记录,它们的所有字段都包含最大数量的“ attemptWrong”,但三元组分别为“ idBook”,“ guidUser”和“ bookmarkLetter”。我以为我可以通过正确使用GROUP BY和MAX运算符来达到此结果。理想的结果是:

idBook  guidUser  bookmarkLetter  letter  attemptWrong
------------------------------------------------------
1       1         100             a       3
1       1         101             b       6
2       2         101             b       3
2       2         152             d       7
3       3         153             e       2

我可以通过此查询获得最大尝试次数

SELECT *,MAX(attemptWrong) as maxAttemptWrong FROM wordstyped GROUP BY idBook, guidUser, bookmarkLetter

但返回

idBook  guidUser  bookmarkLetter  letter  attemptWrong  maxAttemptWrong
-----------------------------------------------------------------------
1       1         100             a       2             3
1       1         101             b       6             6
2       2         101             b       2             3
2       2         152             d       7             7
3       3         153             e       2             2

就像这个小提琴http://sqlfiddle.com/#!9/135cf9/1

因此它将返回正确的maxAttemptWrong,但不会返回正确的记录。我想念什么?

2 个答案:

答案 0 :(得分:2)

即使您使用的是解析功能,我相信您也需要某种子查询来执行此操作。使用MySQL 8之前的方法,我们可以将您的wordstyped表连接到一个子查询,该子查询查找每个书签字母的最大错误尝试次数。这样会将原始表限制为仅在最终输出中需要的匹配行。

SELECT w1.*
FROM wordstyped w1
INNER JOIN
(
    SELECT bookmarkLetter, guidUser, MAX(attemptWrong) AS maxAttemptWrong
    FROM wordstyped
    GROUP BY bookmarkLetter, guidUser
) w2
    ON w1.bookmarkLetter = w2.bookmarkLetter AND
       w1.guidUser = w2.guidUser AND
       w1.attemptWrong = w2.maxAttemptWrong;

答案 1 :(得分:1)

SELECT x.* 
  FROM wordstyped x
  JOIN 
     ( SELECT idbook
            , guiduser
            , bookmarkletter
            , MAX(attemptwrong) attemptwrong
         FROM wordstyped 
        GROUP
           BY idbook
            , guiduser
            , bookmarkletter
     ) y
    ON y.idbook = x.idbook
   AND y.guiduser = x.guiduser
   AND y.bookmarkletter = x.bookmarkletter
   AND y.attemptwrong = x.attemptwrong

http://sqlfiddle.com/#!9/135cf9/9

在我看来,Views在MySQL中几乎完全没有用-但是,如果您必须拥有Views,则可以用这种方式重写上面的代码...

SELECT x.*
  FROM wordstyped x
  LEFT 
  JOIN wordstyped y
    ON y.idbook = x.idbook 
   AND y.guiduser = x.guiduser 
   AND y.bookmarkletter = x.bookmarkletter 
   AND y.attemptwrong > x.attemptwrong 
 WHERE y.idbook IS NULL;

...可伸缩性很差,但至少可以使用视图。