获取每个类别的每个用户的最后记录

时间:2016-08-17 06:36:19

标签: mysql group-by

我想获得每个类别的每个用户的最后一条记录。

例如我有一张桌子

测试(test_id,cat_id,user_id,得分,时间)

我需要每个用户每个类别的最后一条记录。我可以通过category_id或user_id使用group,但是我没有得到如何获得我想要的结果?

例如我有以下记录

test_id | cat_id | user_id | score | time
      1 |      1 |      11 |    20 | 2016-11-12 01:11:11
      2 |      2 |      11 |    24 | 2016-11-12 01:11:11
      3 |      1 |      12 |    25 | 2016-11-12 01:11:11
      4 |      3 |      12 |    21 | 2016-11-12 01:11:11
      5 |      1 |      13 |    22 | 2016-11-12 01:11:11
      6 |      2 |      12 |    23 | 2016-11-12 01:11:11
      7 |      2 |      12 |    27 | 2016-11-12 01:11:11
      8 |      1 |      11 |    21 | 2016-11-12 01:11:11

现在我需要以下结果

test_id | cat_id | user_id | score | time
      2 |      2 |      11 |    24 | 2016-11-12 01:11:11
      3 |      1 |      12 |    25 | 2016-11-12 01:11:11
      4 |      3 |      12 |    21 | 2016-11-12 01:11:11
      5 |      1 |      13 |    22 | 2016-11-12 01:11:11
      7 |      2 |      12 |    27 | 2016-11-12 01:11:11
      8 |      1 |      11 |    21 | 2016-11-12 01:11:11

在上述o / p中,每个用户只有最后一个结果来自每个类别。

3 个答案:

答案 0 :(得分:0)

您需要的查询是:

SELECT l.test_id, l.cat_id, l.user_id, l.score, l.time
FROM tests l                     # "l" from "last"
LEFT JOIN tests n                # "n" from "next"
    ON l.user_id = n.user_id     # match user
    AND l.cat_id = n.cat_id      # and category
    AND l.time <= n.time         # "next" is not before "last" (check the time)
    AND l.test_id < n.test_id    # "next" is after "last" when the times are equal
WHERE n.test_id IS NULL          # there is no "next" matching the JOIN conditions

如何运作

查询将test别名为l(来自“last”),将其别名为n(来自“last”之后的“next”)。 LEFT JOIN确保l中的所有行都包含在联接中。 l中的每一行都与n中包含相同user_idcat_id(“每个用户,每个类别”)的所有行配对,并且列中的值更大timetest_id。因为技术上可以在列user_idcat_idtime中使用相同值的两行,所以在相同的时间匹配来自l的行与来自{{n的行1}}稍后在数据库中输入(它有一个更大的自动递增test_id)。

如果在ON中找不到满足所有n条件的行,则l中的行与满NULL秒的行配对。

WHERE条件仅保留NULLn.test_id的行。它们是来自l的{​​{1}}中没有匹配项的行(因为n列中的n列中没有任何行或更大的值当时间相等时time。这些是每个(用户,类别)对的最后记录。

答案 1 :(得分:-1)

试试这个 $scope.export_excel = (function() { var uri = 'data:application/vnd.ms-excel;base64,' , template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>' , base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) } , format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) } return function(table, name) { if (!table.nodeType) table = document.getElementById(table) var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML} window.location.href = uri + base64(format(template, ctx)) } })()

答案 2 :(得分:-1)

这里我们需要所有类别的最后一个用户。因此,我们必须按类别进行分组,找到时间最长的用户。

SELECT t1.* 
FROM tests t1
INNER JOIN
(
    SELECT max(time) MaxTime,user_id,cat_id
    FROM tests
    GROUP BY user_id,cat_id
) t2
  ON t1.user_id = t2.user_id
  AND t1.cat_id = t2.cat_id
  AND t1.time = t2.MaxTime
order by t1.time desc