我将如何查询该数据集:
SessionId | GameMode | Score
----------|----------|-------
1 | 1 | 100
1 | 1 | 90
1 | 2 | 20
1 | 2 | 15
1 | 3 | 5
1 | 3 | 5
2 | 1 | 90
2 | 1 | 80
2 | 2 | 15
2 | 2 | 15
2 | 3 | 2
2 | 3 | 4
把它变成:
SessionId | GameMode1AvgScore | GameMode2AvgScore | GameMode3AvgScore
----------|--------------------|-------------------|-------------------
1 | 95 | 17.5 | 5
2 | 85 | 15 | 3
为了澄清,我不是在问如何对行进行分组或聚合,我的问题的核心是如何将
GameMode
行旋转到列中? 最佳答案
使用MySQL,要返回指定的结果集,我们需要一个返回四列的查询(SELECT
语句)。
SELECT expr1 AS SessionId
, expr2 AS GameMode1AvgScore
, expr3 AS GameMode2AvgScore
, expr4 AS GameMode3AvgScore
FROM ...
GROUP BY SessionId
MySQL尚未提供“ PIVOT”(ala SQL Server和PostgreSQL)或“ MODEL”(ala Oracle)功能。
因此,就通过SQL SELECT语句实现此结果而言,我们剩下的是老式的条件聚合,
AVG(CASE WHEN t.GameMode = 1 THEN t.Score ELSE NULL END) AS GameMode1AvgScore
这似乎属于您没有问过的“如何对行进行分组或聚合”存储桶。我们可以使用第二条SQL语句来帮助我们构建需要运行的SQL语句,但是似乎仍然属于“如何对行进行分组或聚合”。实际上,任何产生指定结果的SQL语句都将需要汇总行。
因此,从MySQL工具带中排除该工具后,我们得到一个答案:不可能将GamerMode值“透视”到列中。
返回指定结果的语句可能像这样:
SELECT t.sessionid AS SessionId
, AVG(CASE WHEN t.GameMode = 1 THEN t.Score ELSE NULL END) AS GameMode1AvgScore
, AVG(CASE WHEN t.GameMode = 2 THEN t.Score ELSE NULL END) AS GameMode2AvgScore
, AVG(CASE WHEN t.GameMode = 3 THEN t.Score ELSE NULL END) AS GameMode3AvgScore
-- ^ ^
FROM t
GROUP BY t.sessionid
ORDER BY t.sessionid
请注意,返回平均得分的表达式是相同的模式,我们只是在替换
GameMode
的值。为了帮助我们编写查询,我们可以运行初始查询以获取来自同一表的
GameMode
值的不同列表。SELECT q.GameMode FROM t q GROUP BY q.GameMode ORDER BY q.GameMode
或者我们可以查询GameMode的“维度”表(如果存在)。
我们遍历结果集(
GameMode
值)并生成返回每个GameMode
的平均分数所需的表达式。我们可以使用它来构造SQL语句。