SQL:每个id最常见的值

时间:2015-05-28 13:22:19

标签: mysql sql

名为GameEvent的My Table显示如下:

+---------------+-----------+
| sessionNumber | colorName |
+---------------+-----------+
|             1 | Green     |
|             1 | Red       |
|             1 | Green     |
|             1 | Blue      |
|             2 | Blue      |
+---------------+-----------+

我想创建一个Query,它将返回sessionNumber和最常见的颜色,例如sessionNumer 1 - >绿色,sessionNumber 2 - >蓝色。我该怎么做?

2 个答案:

答案 0 :(得分:5)

您从基本聚合查询开始,以获取会话和颜色的计数:

select sessionNumber, colorName, count(*) as cnt
from GameEvent ge
group by sessionNumber, colorName;

然后你真的希望MySQL支持ANSI窗口功能 - 唯一不支持row_number()的主要数据库。但是,唉,这个功能不可用。所以,你有三个选择:

  • 使用字符串聚合技巧。
  • 变量。
  • 复杂SQL。

以下显示了第一种方法:

select sessionNumber,
       substring_index(group_concat(colorName order by cnt desc), ',', 1) as MostCommonColor
from (select sessionNumber, colorName, count(*) as cnt
      from GameEvent ge
      group by sessionNumber, colorName
     ) sc
group by sessionNumber;

请注意,此查询存在限制。 group_concat()的中间结果具有最大长度(由可以更改的参数控制)。此外,如果颜色名称包含逗号,那么您可能希望使用不同的字符。

答案 1 :(得分:4)

您可以做的是使用GROUP BY子句和COUNT()函数选择每对的编号:

SELECT sessionNumber, colorName, COUNT(*) AS numOccurrences
FROM myTable
GROUP BY sessionNumber, colorName;

完成后,您需要找到每个sessionNumber的最大出现次数。这可以通过再次使用聚合来实现:

SELECT sessionNumber, MAX(numOccurrences) AS largestCount
FROM(
  SELECT sessionNumber, colorName, COUNT(*) AS numOccurrences
  FROM myTable
  GROUP BY sessionNumber, colorName) tmp
GROUP BY sessionNumber;

你要做的最后一件事就是将它连接到第一个子查询,条件是会话号和计数匹配,你将得到你需要的sessionNumber和颜色:

SELECT t1.sessionNumber, t1.colorName
FROM(
  SELECT sessionNumber, colorName, COUNT(*) AS numOccurrences
  FROM myTable
  GROUP BY sessionNumber, colorName) t1
JOIN(
  SELECT sessionNumber, MAX(numOccurrences) AS largestCount
  FROM(
    SELECT sessionNumber, colorName, COUNT(*) AS numOccurrences
    FROM myTable
    GROUP BY sessionNumber, colorName) tmp
  GROUP BY sessionNumber) t2
ON t2.sessionNumber = t1.sessionNumber AND t2.largestCount = t1.numOccurrences;

这是一个显示所有三个步骤的SQL Fiddle示例。请务必注意,您不能在此处使用LIMIT,因为该子句将限制整个结果集,而不是单独限制每个组。

相关问题