Запрос на выборку с двух связанных таблиц

Не понимаю, как правильно сделать выборку с двух таблиц. Использую Doctrine. Суть такова: игрок хочет найти подходящую ему игру, если она не находится, то создаётся новая, в которой ожидается противник. И если другой пользователь захочет найти игру, то проходим по всем ожидающим играм и ищем подходящую под тип игры и опыт второго игрока. Если не находим, создаётся новая, и т.д.

То есть:

  1. Проходим по ожидающим играм;
  2. Ищем игры, в которых pending_game.type = желаемому типу игрока. Их всего два: cost и free.
  3. Так же добавить в условие, что опыт игрока и опыт противника могут отличаться только на 100 единиц. То есть, игрок с опытом 500 может играть только с игроками, у которых опыт от больше 400 меньше 600. Например: player.experience = 500, pending_game.player.experience = 550, игрок, который сейчас ищет игру, и тот, кто ожидает противника может встретиться.
CREATE TABLE player
(
    id                       INT AUTO_INCREMENT    NOT NULL,
    name                     VARCHAR(255)          NOT NULL,
    experience               INT         DEFAULT 0 NOT NULL,
    PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8mb4
  COLLATE `utf8mb4_unicode_ci`
  ENGINE = InnoDB
CREATE TABLE pending_game
(
    id        INT AUTO_INCREMENT NOT NULL,
    player_id INT                NOT NULL,
    type      VARCHAR(24)        NOT NULL,
    UNIQUE INDEX UNIQ_57ADA99634DFEB (player_id),
    PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8mb4
  COLLATE `utf8mb4_unicode_ci`
  ENGINE = InnoDB
ALTER TABLE pending_game ADD CONSTRAINT FK_57ADA99634DFEB FOREIGN KEY (player_id) REFERENCES player (id)

Ответы (1 шт):

Автор решения: Akina

Проверка наличия игры:

SELECT id
FROM pending_game pg
JOIN player p1 ON p1.name = @player_name /* или p1.id = @player_id */
JOIN player p2 ON pg.player_id = p2.id 
              AND p2.experience BETWEEN p2.experience - 100 AND p2.experience + 100
WHERE pg.type = @needed_type
ORDER BY pg.id ASC 
/* раскомментировать, если нужна одна игра, иначе вернутся все, пусть выбирает */
-- LIMIT 1 

Если предыдущий запрос не вернул записей (или игрок ничего не выбрал), то

INSERT INTO pending_game (player_id, type)
SELECT id, @needed_type
FROM player
WHERE name = @player_name 
/* или 
INSERT INTO pending_game (player_id, type)
VALUES ( @player_id, @needed_type )
*/

@player_name - имя текущего игрока

@player_id - ID текущего игрока

@needed_type - выбранный тип игры

→ Ссылка