SQL选择按2列排序和按分组

SQL选择按2列排序和按分组,sql,mysql,group-by,sql-order-by,Sql,Mysql,Group By,Sql Order By,这是RS返回和发出的SQL SELECT *, (UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time)) AS T FROM games WHERE game_status > 10 ORDER BY status, T; game_id, player_id, start_time, end_time, score, game_status, is_enabled, T 65, 22, '2009-09-11 17:50:35'

这是RS返回和发出的SQL

SELECT *, (UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time)) AS T
 FROM games
WHERE game_status > 10
ORDER BY status, T;


game_id, player_id, start_time, end_time, score, game_status, is_enabled, T
65, 22, '2009-09-11 17:50:35', '2009-09-11 18:03:07', 17, 11, 1, 752
73, 18, '2009-09-11 18:55:07', '2009-09-11 19:09:07', 30, 11, 1, 840
68, 20, '2009-09-11 18:03:08', '2009-09-11 18:21:52', 48, 11, 1, 1124
35, 18, '2009-09-11 15:46:05', '2009-09-11 16:25:10', 80, 11, 1, 2345
13, 8, '2009-09-11 12:33:31', '2009-09-11 15:21:11', 40, 11, 1, 10060
11, 5, '2009-09-11 12:22:34', '2009-09-11 15:21:42', 55, 11, 1, 10748
34, 17, '2009-09-11 15:45:43', '2009-09-11 21:00:45', 49, 11, 1, 18902
2, 1, '2009-09-10 20:46:59', '2009-09-11 23:45:21', 3, 11, 1, 97102
84, 1, '2009-09-11 23:51:29', '2009-09-11 23:51:42', 10, 12, 1, 13

我想按玩家id分组(即,每个玩家id取最佳结果,由“游戏状态-分钟”和时间T决定)

所以我添加了一个GROUPBY子句,但它不返回min

SELECT *, (UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time)) AS T
 FROM games
WHERE game_status > 10
GROUP BY player_id
ORDER BY game_status, T;

35, 18, '2009-09-11 15:46:05', '2009-09-11 16:25:10', 80, 11, 1, 2345
13, 8, '2009-09-11 12:33:31', '2009-09-11 15:21:11', 40, 11, 1, 10060
34, 17, '2009-09-11 15:45:43', '2009-09-11 21:00:45', 49, 11, 1, 18902
1, 1, '2009-09-10 20:39:44', '2009-09-10 20:41:21', 10, 12, 1, 97
24, 12, '2009-09-11 14:46:06', '2009-09-11 14:53:30', 10, 12, 1, 444
5, 3, '2009-09-11 10:56:22', '2009-09-11 11:13:01', 11, 12, 1, 999
37, 20, '2009-09-11 15:51:13', '2009-09-11 16:15:04', 14, 12, 1, 1431
79, 31, '2009-09-11 20:34:17', '2009-09-11 20:43:29', 4, 13, 1, 552
18, 9, '2009-09-11 13:09:47', '2009-09-11 18:33:10', 2, 13, 1, 19403
72, 30, '2009-09-11 18:46:29', '2009-09-11 18:48:44', 0, 14, 1, 135
40, 22, '2009-09-11 16:12:39', '2009-09-11 16:18:23', 3, 14, 1, 344
8, 5, '2009-09-11 12:15:54', '2009-09-11 12:21:48', 25, 14, 1, 354
85, 33, '2009-09-12 01:14:01', '2009-09-12 01:20:43', 0, 14, 1, 402
22, 11, '2009-09-11 13:50:41', '2009-09-11 13:57:24', 7, 14, 1, 403


SELECT *, min(UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time)) AS T
 FROM games
WHERE game_status > 10
GROUP BY player_id
ORDER BY game_status, T;
如果选择min(T),它不会返回min行,而是返回hold列上的min值

我搜索了一些带有自连接的方法,比如

子查询SELECT for min(),但我不能对两列发出两个min(),因为它不会返回我想要的特定行

select type, min(price) as minprice
from fruits
group by type;

我希望有一种方法可以作为第一个SQL上的筛选器来删除重复的player_id行。

看起来您缺少了MIN函数,并且对筛选子句做了一些细微的更改

例如:

SELECT *, MIN(UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time)) AS T 
FROM games 
GROUP BY player_id 
HAVING MIN(UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time)) > 10
ORDER BY game_status, T;
我移动了“>10”逻辑,因为我相信您的意图是过滤掉那些最佳游戏状态小于10的玩家。这与过滤掉任何小于10的单个游戏状态条目(这是您通过WHERE子句所做的)是不同的标准


试试看。看起来你在使用MySQL,这不是我所熟悉的数据库系统。

从我收集的信息来看,你想看看给定的
玩家id
游戏id
组合在最高
游戏状态下的最短时间是多少。试试这个:

select
    g1.game_id,
    g1.player_id,
    min(UNIX_TIMESTAMP(g1.end_time) - UNIX_TIMESTAMP(g1.start_time)) as t,
    g1.game_status
from
    games g1
    inner join (select game_id, player_id, max(game_status) as max_status 
                from games where game_status > 10) g2 on
        g1.game_id = g2.game_id
        and g1.player_id = g2.player_id
        and g1.game_status = g2.max_status
group by
    g1.game_id,
    g1.player_id,
    g1.game_status
order by
    g1.player_id,
    g1.game_id,
    g1.game_status,
    T

我对您问题中的某些短语有点不确定,但您需要按照以下行执行嵌套选择操作:

SELECT g.*
  FROM (SELECT *,
               (UNIX_TIMESTAMP(g.end_time) - UNIX_TIMESTAMP(g.start_time)) AS t
          FROM games
       ) AS g
       JOIN (SELECT player_id,
                    MIN(UNIX_TIMESTAMP(end_time) -
                        UNIX_TIMESTAMP(start_time)) AS min_t
               FROM games
              WHERE game_status > 10
              GROUP BY player_id
             ) AS r
      ON g.player_id = r.player_id AND g.t = r.min_t
ORDER BY game_status, g.t;
“r”查询返回该玩家的玩家ID和相应的最短时间;该ID与主表连接,主表以相同的最短时间获取该玩家的所有行。通常,这将是一个条目,但如果有人同时有两个游戏,则查询将同时返回这两个条目


我不清楚是否有其他方法可以消除结果集的歧义;可能有。

谢谢您的回复

我在寻找埃里克和乔纳森的解决方案

让我详细解释一下

正如Eric提到的,我正在从game_status和min time(T)中寻找结果, 我只需要状态>10,并从较小的排名, (即11>12>13>14,只有四种状态)并从其时间确定

我从表中取出了前5行player_id=18:

选择*,(UNIX时间戳(结束时间)-UNIX时间戳(开始时间))作为T 来自玩家id=18的游戏,按游戏状态排序,T

game_id, player_id, start_time, end_time, score, game_status, is_enabled, T
73, 18, '2009-09-11 18:55:07', '2009-09-11 19:09:07', 30, 11, 1, 840
35, 18, '2009-09-11 15:46:05', '2009-09-11 16:25:10', 80, 11, 1, 2345
53, 18, '2009-09-11 16:57:30', '2009-09-11 16:58:28', 0, 14, 1, 58
59, 18, '2009-09-11 17:27:42', '2009-09-11 17:28:51', 0, 14, 1, 69
57, 18, '2009-09-11 17:24:25', '2009-09-11 17:25:41', 0, 14, 1, 76
玩家18在游戏中玩了很多次。他得到了不同的结果(游戏状态)。 现在,我们在每个球员身上都取得了最好的成绩

显然,18年的最佳结果是

73, 18, '2009-09-11 18:55:07', '2009-09-11 19:09:07', 30, 11, 1, 840
因为状态是11,时间是840


请注意,他所用的最佳时间是game_id=53(上面第3行),我们不会接受这个结果,因为状态是14。因此,使用min(UnixTimeSTAMP…)将不会有帮助,因为它将58作为结果集。

什么是“保留列”?另外,“它由game_status-the min决定”,时间t是什么意思?您好,这是表格字段:游戏id、玩家id、开始时间、结束时间、分数、游戏状态、已启用且时间T为cal by(UNIX时间戳(结束时间)-UNIX时间戳(开始时间))因为我想取最小的game_status,它的game_status>10,即排序为11>12>13…嗨,thx用于回答,我使用了WHERE子句来过滤掉“game_status<10”项。但是,如果我添加了一个min(T),则有一些“game_status<10”值,它从小于10行的game_status返回一些值。而从其他行返回game_status,它似乎加入了自身并获取了原始表中不存在的一行。如果您将选择列表更改为仅包含player_id和T,会发生什么情况?请进一步解释,player_id来自另一个表,它是每个玩家的唯一id。还有game_id,是pr这张桌子上的许多游戏我都在寻找每个玩家的最佳结果,因为每个玩家都有多个游戏。