我需要为每节课获得每个game_id的第一和最高分数:
--------------------------------------------
|id |lesson_id |game_id |score |date |
--------------------------------------------
|1 |1 |0 |20 |1391627323 |
|2 |1 |0 |80 |1391627400 |
|3 |1 |1 |5 |1391627543 |
|4 |1 |2 |7 |1391627450 |
|5 |2 |0 |90 |1391627323 |
|6 |2 |1 |10 |1391628000 |
|7 |2 |2 |8 |1391628005 |
|8 |2 |2 |9 |1391628010 |
|9 |2 |0 |95 |1391628333 |
|10 |3 |0 |50 |1391627323 |
--------------------------------------------
我需要这个输出:
---------------------------------------------------
| |game_id = 0 |game_id = 1 |game_id = 2 |
|lesson_id |first |max |first |max |first |max |
---------------------------------------------------
|1 |20 |80 |5 |5 |7 |7 |
|2 |90 |95 |10 |10 |8 |9 |
|3 |50 |50 |- |- |- |- |
---------------------------------------------------
到目前为止,我有这个,每个game_id(第一个和最大)得到一行,但显然这些值需要在同一行:
SELECT game_id, lesson_id, MAX(score) AS max_score, MIN(date), score AS first_score FROM cdu_user_progress
GROUP BY game_id
有人提供任何帮助吗?
答案 0 :(得分:0)
我猜您正在使用MySQL,因为您的示例查询在大多数其他数据库中在语法上都是不正确的。
您需要条件聚合。第一个得分很棘手:
select lesson_id,
substring_index(group_concat(case when game_id = 1 then score end order by date),
',', 1) as game1_first,
max(case when game_id = 1 then score end) as game2_max,
substring_index(group_concat(case when game_id = 2 then score end order by date),
',', 1) as game2_first,
max(case when game_id = 2 then score end) as game1_max,
substring_index(group_concat(case when game_id = 3 then score end order by date),
',', 1) as game3_first,
max(case when game_id = 3 then score end) as game3_max
from cdu_user_progress
GROUP BY lesson_id;
如果您的游戏数量未知,那么您必须将SQL构造为字符串,然后使用prepare或其他界面来执行它。
答案 1 :(得分:0)
如果你有几个game_id值,你可以尝试这样的事情:
SELECT x.lesson_id,
MAX(CASE WHEN x.game_id=0 THEN x.scorefirst ELSE 0 END) AS first0,
MAX(CASE WHEN x.game_id=0 THEN y.score ELSE 0 END) AS max0,
MAX(CASE WHEN x.game_id=1 THEN x.scorefirst ELSE 0 END) AS first1,
MAX(CASE WHEN x.game_id=1 THEN y.score ELSE 0 END) AS max1,
MAX(CASE WHEN x.game_id=2 THEN x.scorefirst ELSE 0 END) AS first2,
MAX(CASE WHEN x.game_id=2 THEN y.score ELSE 0 END) AS max2,
FROM (SELECT t1.lesson_id, t1.game_id, t1.score AS score first, t1.date
FROM cdu_user_progress t1 INNER JOIN
cdu_user_progress t2 ON t1.lesson_id=t2.lesson_id
AND t1.game_id =t2.game_id AND t1.date>=t2.date
GROUP BY t1.lesson_id, t1.game_id, t1.score, t1.date
HAVING COUNT(*)=1) x INNER JOIN
cdu_user_progress y ON x.lesson_id=y.lesson_id AND x.game_id = y.game_id
GROUP BY x.lesson_id
否则你应该以编程方式完成
答案 2 :(得分:0)
我可能分两步完成 - 首先,我会以行格式获得结果,然后在另一个查询中使用它将它们移动到列中。
SELECT g.lesson_id,
g.game_id,
c.score AS first,
g.max_score
FROM (
SELECT lesson_id,
game_id,
MAX(score) AS max_score,
MIN(date) AS min_date
FROM cdu_user_progress
GROUP BY lesson_id, game_id
) g
LEFT JOIN dbo.cdu_user_progress c
ON g.lesson_id = c.lesson_id
AND g.game_id = c.game_id
AND g.min_date = c.date
不,根据您期望的列数,您可以围绕该列编写查询以将其拉入列中。注意:在SQL Server中,可能值得查看PIVOT命令。
离。
SELECT lesson_id,
MAX(CASE WHEN p.game_id = 0
THEN p.first
END) AS game_id0_first,
MAX(CASE WHEN p.game_id = 0
THEN p.max_score
END) AS game_id0_max
-- Add other columns here
FROM (
SELECT g.lesson_id,
g.game_id,
c.score AS first,
g.max_score
FROM (
SELECT lesson_id,
game_id,
MAX(score) AS max_score,
MIN(date) AS min_date
FROM cdu_user_progress
GROUP BY lesson_id, game_id
) g
LEFT JOIN dbo.cdu_user_progress c
ON g.lesson_id = c.lesson_id
AND g.game_id = c.game_id
AND g.min_date = c.date
) p
GROUP BY p.lesson_id