Возможен ли этот запрос? - PullRequest
       2

Возможен ли этот запрос?

1 голос
/ 10 августа 2010

Извините заранее за массовые запросы.Я пытался и не могу на всю жизнь заставить этот запрос работать.Это добавляет выигрыши и потери обоим пользователям, когда два вошедших в игру пользователя играют друг против друга.(Это каменные ножницы).Я могу заставить его работать для одного пользователя, но когда я пытаюсь собрать «таблицу статистики», суммирующую пользователей, я получаю дубликаты.

Вот мой сокращенный радикраткости схема

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

Хорошоудачи и спасибо!

Ответы [ 2 ]

0 голосов
/ 07 июля 2012

Надеюсь, это поможет!

Два основных способа:

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;

на самом деле оба эти одинаковые!

но я хочу показать второйуродливо, потому что гораздо лучше использовать представления!

Я фанат оракула, надеюсь, синтаксис в вашей среде правильный.

Удачи.

0 голосов
/ 10 августа 2010

В настоящее время ваш дизайн стола не нормализован должным образом - у вас всегда будет два разных игрока, связанных с каждой записью rps_session и rps_game.Если бы у меня был выбор, я бы нормализовал их, чтобы между каждым из них и таблицей rps_user была таблица ссылок.

Сказав это, есть большая вероятность, что вы не сможете этого сделать, поэтому естьпростой ответ: просто разделите число выигрышей, проигрышей и связей из второго запроса на 2. Это всегда должно работать, так как для каждой игры, где один пользователь - user1, другой пользователь - user2 - именно поэтому вы видите двойные значения.

Примечание.Если отношения между тремя таблицами в вашей реальной системе более сложны, чем то, что вы здесь представили (так что вы не можете полагаться на то, что в каждой игре всегда будет два пользователя), это решение не будетбыть надежным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...