提前抱歉进行大量查询。我一直在努力,不能为我的生活让这个查询工作。当两个登录用户互相对战时,它会为两个用户增加输赢。 (这是石头剪刀)。我可以让它适用于单个用户,但是当我尝试收集对用户进行总结的“统计表”时,我得到了重复。
这是我的缩写为简洁架构
create table rps_user (
user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(255),
PRIMARY KEY (user_id),
UNIQUE (username)
);
CREATE TABLE rps_session (
session_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
player1_user_id INT UNSIGNED DEFAULT NULL,
player2_user_id INT UNSIGNED DEFAULT NULL,
connected BOOLEAN DEFAULT 0,
PRIMARY KEY (session_id)
);
CREATE TABLE rps_game (
game_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
game_number INT UNSIGNED DEFAULT NULL,
session_id INT UNSIGNED NOT NULL,
player1_choice ENUM('ROCK','PAPER','SCISSORS') DEFAULT NULL,
player2_choice ENUM('ROCK','PAPER','SCISSORS') DEFAULT NULL,
PRIMARY KEY (game_id)
);
这是我的查询有效
SELECT IF((player1_choice + 1) % 3 + 1 = player2_choice + 0 AND player1_user_id = rps_user.user_id OR
(player2_choice + 1) % 3 + 1 = player1_choice + 0 AND player2_user_id = rps_user.user_id, 1, 0) AS win,
IF(player1_choice = player2_choice, 1, 0) as tie,
IF(player1_choice % 3 + 1 = player2_choice + 0 AND player1_user_id = rps_user.user_id OR
player2_choice % 3 + 1 = player1_choice + 0 AND player2_user_id = rps_user.user_id, 1, 0) AS loss
FROM rps_game INNER JOIN rps_session USING (session_id)
INNER JOIN rps_user ON rps_session.player1_user_id = rps_user.user_id OR rps_session.player2_user_id = rps_user.user_id
WHERE player1_choice IS NOT NULL AND player2_choice IS NOT NULL and rps_user.user_id = ?
那个没有
的那个SELECT username, SUM(IF((player1_choice + 1) % 3 + 1 = player2_choice + 0 AND player1_user_id = rps_user.user_id OR
(player2_choice + 1) % 3 + 1 = player1_choice + 0 AND player2_user_id = rps_user.user_id, 1, 0)) AS wins,
SUM(IF(player1_choice = player2_choice, 1, 0)) AS ties,
SUM(IF(player1_choice % 3 + 1 = player2_choice + 0 AND player1_user_id = rps_user.user_id OR
player2_choice % 3 + 1 = player1_choice + 0 AND player2_user_id = rps_user.user_id, 1, 0)) AS losses
FROM rps_game INNER JOIN rps_session USING (session_id)
INNER JOIN rps_user ON rps_session.player1_user_id = rps_user.user_id OR rps_session.player2_user_id = rps_user.user_id
WHERE player1_choice IS NOT NULL AND player2_choice IS NOT NULL
GROUP BY user_id ORDER BY wins DESC
祝你好运,谢谢!
答案 0 :(得分:0)
目前,您的桌面设计未正确规范化 - 您将始终拥有与每个rps_session和rps_game记录相关联的两个不同的玩家。根据我的选择,我会对这些进行规范化,以便在它们和rps_user表之间有一个链接表。
话虽如此,你很有可能无法做到这一点,所以有一个简单的答案:简单地将第二个查询中的胜利,损失和关系数字除以2.这应该始终有效,就像每一个一个用户是user1,另一个用户是user2的游戏 - 这就是你看到双倍值的原因。
NB。如果您实际系统中三个表之间的关系比您在此处呈现的更复杂(因此您不能依赖每个游戏总共有两个用户),此解决方案将不可靠。
答案 1 :(得分:0)
我希望这有帮助!
两种主要方式:
1-小巧,易于理解,易于后续更改
2-大,更复杂,难以改变!
让我们先试一下:
create view stats as
YOUR_FIRST_BIG_QUERY_HERE;
现在简单易行:
select USER_ID,sum(wins),sum(ties), sum(loses)
from stats /*this is our new created view*/
group by USER_ID;
很容易!
现在虽然一个!!
我们在这里使用子查询:
select USER_ID,sum(wins),sum(ties), sum(loses)
from (SELECT IF((player1_choice + 1) % 3 + 1 = player2_choice + 0 AND player1_user_id = rps_user.user_id OR
(player2_choice + 1) % 3 + 1 = player1_choice + 0 AND player2_user_id = rps_user.user_id, 1, 0) AS win,
IF(player1_choice = player2_choice, 1, 0) as tie,
IF(player1_choice % 3 + 1 = player2_choice + 0 AND player1_user_id = rps_user.user_id OR
player2_choice % 3 + 1 = player1_choice + 0 AND player2_user_id = rps_user.user_id, 1, 0) AS loss
FROM rps_game INNER JOIN rps_session USING (session_id)
INNER JOIN rps_user ON rps_session.player1_user_id = rps_user.user_id OR rps_session.player2_user_id = rps_user.user_id
WHERE player1_choice IS NOT NULL AND player2_choice IS NOT NULL)
group by USER_ID;
实际上这两者都是一样的!
但我想展示第二个丑陋,因为使用视图要好得多!
我是oracle的粉丝,希望你的环境语法正确。
祝你好运。