条件查询以查找玩家正在参加和受邀参加的游戏

问题描述 投票:0回答:1

对于每个玩家,在“表现合理”查询中显示他们当前的游戏和邀请。

|   PLAYERS   |    |      GAMES     |  
|  ID  | Name |    | ID  |   Name   |
|------|------|    |-----|----------|
|  1   | Abby |    |  1  | Baccarat |
|  2   | Billy|    |  2  | BlackJack|
|  3   | Cary |    |  3  | Craps    |
|  4   | Dolly|    |  4  | Roulette |
|  5   | Eddy |

通过列表邀请玩家参加游戏。该列表可以随时更改,因此玩家可能会被邀请参加游戏,然后从以下列表中的游戏中删除:

|LIST|  |        INVITE             |
| ID |  | ID | LIST | PLAYER | GAME |
|----|  |----|------|--------|------|
| 1  |  |  1 |  1   |    1   |   2  |
| 2  |  |  2 |  1   |    2   |   2  |
| 3  |  |  3 |  1   |    3   |   2  |
| 4  |  |  4 |  1   |    4   |   2  |
| 5  |  |  5 |  1   |    5   |   2  |
| 6  |  |  6 |  2   |    1   |   2  |
| 7  |  |  7 |  2   |    2   |   2  |
| 8  |  |  8 |  2   |    3   |   2  |
| 9  |  |  9 |  2   |    4   |   2  |
        | 10 |  3   |    1   |   4  |
        | 11 |  3   |    2   |   4  |
        | 12 |  3   |    5   |   4  |
        | 13 |  4   |    4   |   1  |
        | 14 |  4   |    5   |   1  |
        | 15 |  5   |    1   |   4  |
        | 16 |  5   |    4   |   4  |
        | 17 |  5   |    5   |   4  |
        | 18 |  6   |    4   |   4  |
        | 19 |  6   |    5   |   4  |
        | 20 |  7   |    1   |   4  |
        | 21 |  7   |    2   |   4  |
        | 22 |  7   |    3   |   4  |
        | 23 |  7   |    4   |   4  |
        | 24 |  7   |    5   |   4  |
        | 25 |  8   |    1   |   3  |
        | 26 |  8   |    2   |   3  |
        | 27 |  8   |    3   |   3  |
        | 28 |  8   |    4   |   3  |

在进行一轮游戏之前,列表可以更新零次或多次。游戏开始时,该回合标记为开始,完成时标记为结束。

|           ROUND    |        |
|  ID  | Game | List | State  |
|------|------|------|--------|
|  1   | 2    | 1    |FINISHED|
|  2   | 2    | 2    |FINISHED|
|  3   | 2    | 2    |STARTED |
|  4   | 4    | 3    |STARTED |
|  5   | 3    | 8    |STARTED |

玩家完成的游戏:

SELECT * FROM GAMES G 
JOIN INVITE I ON I.GAME = G.ID
JOIN PLAYER P ON P.ID   = I.PLAYER
JOIN ROUND  R ON G.ID   = R.GAME
WHERE R.STATE = 'FINISHED'

但我正在努力对当前游戏和邀请进行条件查询。我认为当前的游戏查询是:

SELECT * FROM GAMES G 
JOIN INVITE I ON I.GAME = G.ID
JOIN PLAYER P ON P.ID   = I.PLAYER
JOIN ROUND  R ON G.ID   = R.GAME
WHERE R.STATE = 'STARTED'

我认为邀请部分是:

SELECT * FROM GAMES G 
JOIN INVITE I ON I.GAME = G.ID
JOIN PLAYER P ON P.ID   = I.PLAYER
WHERE I.LIST            = (
  SELECT MAX(LL.ID) 
  FROM LIST LL 
  WHERE         LL.GAME = G.ID
)

但我很难将这些结合起来,以及这是否是一个“性能合理”的解决方案。

期望的结果

列表执行以下操作:

  1. 每个人都看到二十一点。
  2. 将 Eddy 和 Dolly 从 BlackJack 中移除
  3. 为艾比、比利和艾迪添加轮盘赌
  4. 为多莉和艾迪添加百家乐
  5. 从百家乐中删除比利并添加多莉
  6. 将艾比从百家乐中删除
  7. 从百家乐中删除多莉和艾迪,并添加艾比、比利和卡里
  8. 将比利、卡里和多莉添加到掷骰子游戏中

回合执行以下操作:

  1. 以列表 #1 开始并完成二十一点
  2. 使用列表 #2 开始并完成二十一点
  3. 以列表 #2 开始二十一点
  4. 开始轮盘赌列表#3
  5. 以列表 #8 开始掷骰子

每个参与者登录时,他们都会看到受邀并可能开始的游戏列表;当游戏进行时,他们可以看到游戏。游戏结束后,他们只有在最近的列表中被(重新)邀请才能看到游戏。单独的查询用于查看每个玩家所参加的已完成游戏。某些列表永远不会应用于一轮。

给定玩家ID,显示当前游戏和邀请游戏的列表。例如,对于 Abby,一旦创建了列表 #1,Abby 就会看到 BlackJack;当第一轮开始时,艾比看到了二十一点;创建列表 2 后,Abby 继续看到 BlackJack

sql postgresql
1个回答
0
投票

虽然我发现它有点难以理解,但我已经可以说这么多了:邀请表看起来很糟糕,我认为它违反了数据库规范化规则。

似乎每个列表都指的是一款游戏。所以游戏ID应该是列表表中的属性,而不是邀请表中的属性,也不是回合表中的属性。

CREATE TABLE player (
  id_player SERIAL PRIMARY KEY,
  name      VARCHAR(10)
);

CREATE TABLE game (
  id_game SERIAL PRIMARY KEY,
  name    VARCHAR(10)
);

CREATE TABLE list (
  id_list SERIAL PRIMARY KEY,
  id_game INTEGER NOT NULL REFERENCES game
);

CREATE TABLE invite (
  id_invite SERIAL PRIMARY KEY,
  id_list   INTEGER NOT NULL REFERENCES list,
  id_player INTEGER NOT NULL REFERENCES player
);

CREATE TABLE round (
  id_round SERIAL PRIMARY KEY,
  id_list  INTEGER NOT NULL REFERENCES list,
  status   VARCHAR(10)
);

现在,如果我理解正确的话,该列表将被解释为每场比赛的历史记录。因此,对于每款游戏,我们都会查看其最新列表,以了解当前邀请哪些玩家参加该游戏。

在你的例子中

  • 游戏 1 的最新列表是列表 4
  • 游戏 2 的最新列表是列表 2
  • 游戏 3 的最新列表是列表 8。
  • 游戏 4 的最新列表是列表 7

其他列表只是历史,我们不必看。

现在您想要显示仍邀请玩家参加的所有游戏的所有回合。类似的东西

WITH
  latest_lists AS
  (
    SELECT id_game, MAX(id_list) AS last_id_list
    FROM list
    GROUP BY id_game
  )
SELECT p.name, r.id_round, g.name, r.status
FROM round r
JOIN latest_lists ll ON ll.last_id_list = r.id_list
JOIN game g ON g.id_game = ll.id_game
JOIN invite i ON i.id_list = ll.last_id_list
JOIN player p ON p.id_player = i.id_player
ORDER BY p.name, r.id_round;

演示:https://dbfiddle.uk/fdcFvPuD

© www.soinside.com 2019 - 2024. All rights reserved.