从一列获取MAX值,从另一列获取MIN

时间:2014-07-15 20:42:52

标签: mysql

我一直在制作一款基于Candy Crush的游戏。 Score表有以下三列:

stage_level_id                        | value | moves
------------------------------------------------------
9f7678f0-fc8f-11e3-a398-b2227cce2b53  | 35000 | 350
9f7678f0-fc8f-11e3-a398-b2227cce2b53  | 35000 | 500
9f7678f0-fc8f-11e3-a398-b2227cce2b54  | 15000 | 125
9f7678f0-fc8f-11e3-a398-b2227cce2b54  | 13500 | 100
9f7678f0-fc8f-11e3-a398-b2227cce2b55  | 12500 | 350
9f7678f0-fc8f-11e3-a398-b2227cce2b55  | 7500  | 25

我需要按stage_level_id分组得出最高分数。如果stage_level_id具有相同的Value(以53结尾),则必须返回Moves个最小的行。

我正在尝试以下操作,但它没有按预期工作:

SELECT a.stage_level_id, MAX(a.value) as max_value, a.moves
FROM scores a
LEFT JOIN scores b ON (
  a.stage_level_id = b.stage_level_id
)
RIGHT JOIN scores c ON (
  c.moves = ( SELECT MIN(moves) as moves FROM scores WHERE c.stage_level_id =         a.stage_level_id )
)
WHERE a.player_id = 1475332386040815
GROUP BY a.stage_level_id

预期结果是:

stage_level_id                        | value | moves
------------------------------------------------------
9f7678f0-fc8f-11e3-a398-b2227cce2b53  | 35000 | 350
9f7678f0-fc8f-11e3-a398-b2227cce2b54  | 15000 | 125
9f7678f0-fc8f-11e3-a398-b2227cce2b55  | 12500 | 350

我做错了什么?

4 个答案:

答案 0 :(得分:2)

你的尝试还远远不够。你错过了第一个JOIN ... ON子句的必要部分,第二个JOIN是不必要的。

SELECT tbl1.stage_level_id, tbl1.max_value, MIN(s.moves) AS moves
FROM 
(
  SELECT stage_level_id, MAX(value) AS max_value
  FROM scores
  GROUP BY stage_level_id
) tbl1
LEFT JOIN scores s ON tbl1.stage_level_id = s.stage_level_id AND tbl1.max_value = s.value
GROUP BY stage_level_id

DEMO

答案 1 :(得分:2)

您可以使用NOT EXISTS

获取每个(stage_id,max score)组的最小移动次数
select stage_level_id, max(value), min(moves)
from scores s1
where not exists (
    select 1 from scores s2
    where s2.stage_level_id = s1.stage_level_id
    and s2.value > s1.value
)
group by stage_level_id;

not exists部分将结果限制为仅在每个组中具有最高分数的行(换句话说,不存在组内具有更高分数的其他行)。

此查询可以利用(stage_id,value)

上的综合索引

http://sqlfiddle.com/#!2/88ee6/8

答案 2 :(得分:0)

实际上,这可以简单地通过一个globals.php和一个$smarty->assign()和一个$smarty来完成:

select

left join给出:

group by

select s1.stage_level_id, s1.score, min(s1.moves) as moves from scores s1 left join scores s2 on s2.stage_level_id = s1.stage_level_id and s2.score > s1.score where s2.score IS NULL group by s1.stage_level_id; 子句选择每个left join中包含最高分数的行:

| s1                                                   | s2                                                     |
|--------------------------------------|-------|-------|--------------------------------------|--------|--------|
| stage_level_id                       | score | moves | stage_level_id                       | score  | moves  |
| 9f7678f0-fc8f-11e3-a398-b2227cce2b53 | 35000 | 350   | (null)                               | (null) | (null) |
| 9f7678f0-fc8f-11e3-a398-b2227cce2b53 | 35000 | 500   | (null)                               | (null) | (null) |
| 9f7678f0-fc8f-11e3-a398-b2227cce2b54 | 15000 | 125   | (null)                               | (null) | (null) |
| 9f7678f0-fc8f-11e3-a398-b2227cce2b54 | 13500 | 100   | 9f7678f0-fc8f-11e3-a398-b2227cce2b54 | 15000  | 125    |
| 9f7678f0-fc8f-11e3-a398-b2227cce2b55 | 7500  | 25    | 9f7678f0-fc8f-11e3-a398-b2227cce2b55 | 12500  | 350    |
| 9f7678f0-fc8f-11e3-a398-b2227cce2b55 | 12500 | 350   | (null)                               | (null) | (null) |

以便我们可以在where制定的每个stage_level_id组上运行| s1 | s2 | |--------------------------------------|-------|-------|----------------|--------|--------| | stage_level_id | score | moves | stage_level_id | score | moves | | 9f7678f0-fc8f-11e3-a398-b2227cce2b53 | 35000 | 350 | (null) | (null) | (null) | | 9f7678f0-fc8f-11e3-a398-b2227cce2b53 | 35000 | 500 | (null) | (null) | (null) | | 9f7678f0-fc8f-11e3-a398-b2227cce2b54 | 15000 | 125 | (null) | (null) | (null) | | 9f7678f0-fc8f-11e3-a398-b2227cce2b55 | 12500 | 350 | (null) | (null) | (null) | 以获得最终结果:

min(s1.moves)

stage_level_id

http://sqlfiddle.com/#!9/50ed8/6/0进行测试。

答案 3 :(得分:0)

不确定我是否误解了这个问题,但不是那么简单吗?

SELECT column1, max(column2), IF(column1 like "%53", min(column3), max(column3))
FROM test
GROUP BY column1
;

检查一下,SQLFiddle link