我有下表:
CREATE TABLE `score` (
`score_id` int(10) unsigned NOT NULL auto_increment,
`user_id` int(10) unsigned NOT NULL,
`game_id` int(10) unsigned NOT NULL,
`thescore` bigint(20) unsigned NOT NULL,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`score_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
这是一个分数表,用于存储user_id和game_id以及每个游戏的得分。 每场比赛的前3个位置都有奖杯。 我有一个user_id,我想检查一下这个特定用户是否从任何游戏中获得了任何奖杯。
我可以以某种方式创建此查询而无需创建临时表吗?
答案 0 :(得分:1)
SELECT game_id, user_id
FROM score score1
WHERE (SELECT COUNT(*) FROM score score2
WHERE score1.game_id = score2.game_id AND score2.thescore > score1.thescore) < 3
ORDER BY game_id ASC, thescore DESC;
答案 1 :(得分:1)
更明确的方式,并且已经完成了。
SELECT DISTINCT user_id FROM ( select s.user_id, s.game_id, s.thescore, (SELECT count(1) from scores where game_id = s.game_id AND thescore > s.thescore ) AS acount FROM scores s ) AS a
WHERE acount&lt; 3
答案 2 :(得分:1)
SELECT s1.*
FROM score s1 LEFT OUTER JOIN score s2
ON (s1.game_id = s2.game_id AND s1.thescore < s2.thescore)
GROUP BY s1.score_id
HAVING COUNT(*) < 3;
此查询返回所有获胜游戏的行。虽然包括关系;如果分数是10,16,16,16,18那么有四个获胜者:16,16,16,18。我不确定你是怎么处理的。您需要一些方法来解决连接条件中的关系。
例如,如果先前的游戏获胜解决了关系,那么您可以通过这种方式修改查询:
SELECT s1.*
FROM score s1 LEFT OUTER JOIN score s2
ON (s1.game_id = s2.game_id AND (s1.thescore < s2.thescore
OR s1.thescore = s2.thescore AND s1.score_id < s2.score_id))
GROUP BY s1.score_id
HAVING COUNT(*) < 3;
您还可以使用timestamp
列来解决关系,如果您可以依赖UNIQUE
。
然而,MySQL倾向于为这种查询创建一个临时表。以下是此查询的EXPLAIN
输出:
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| 1 | SIMPLE | s1 | ALL | NULL | NULL | NULL | NULL | 9 | Using temporary; Using filesort |
| 1 | SIMPLE | s2 | ALL | PRIMARY | NULL | NULL | NULL | 9 | |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
答案 3 :(得分:0)
没有测试,但应该可以正常工作:
SELECT
*,
@position := @position + 1 AS position
FROM
score
JOIN (SELECT @position := 0) p
WHERE
user_id = <INSERT_USER_ID>
AND game_id = <INSERT_GAME_ID>
ORDER BY
the_score
在那里你可以检查位置字段,看它是否在1到3之间。