寻求有关完成SQL查询的建议

时间:2017-02-19 23:06:17

标签: sql postgresql

所以我有2个SQL表

玩家:

P_Id 
Name

匹配

M_Id
Player1
Player2
Winner

应该是自我解释,如果我们有一个比赛ID 5涉及球员1和球员2,其中2是赢家,那么行将是

(5, 1, 2, 2)

如何按照赢得的比赛的降序获取(p_id, total_wins)格式的所有玩家列表?

我已经想出了如何通过

获得单人游戏的总胜利
"SELECT count(m_id) FROM Matches where winner = <p_id>;"

编辑:

tournament=> select winner, count(winner) from matches group by winner;
 winner | count
--------+-------
      1 |     1
      5 |     1
      3 |     1
      7 |     1
(4 rows)

tournament=> select * from players;
 p_id |       name
------+-------------------
    1 | Twilight Sparkle
    2 | Fluttershy
    3 | Applejack
    4 | Pinkie Pie
    5 | "Rarity
    6 | Rainbow Dash
    7 | Princess Celestia
    8 | Princess Luna

我可以在胜利者== p_id的地方加入这两个吗?你能解释一下我需要什么样的联接吗?

2 个答案:

答案 0 :(得分:1)

SELECT Players.*, NumberOfMatchesWon
FROM Players
JOIN (
    SELECT Winner AS P_Id, COUNT(*) AS NumberOfMatchesWon
    FROM Matches
    GROUP BY Winner
) AS NumberOfMatchesWonByPlayer USING (P_Id)
ORDER BY NumberOfMatchesWon DESC

名称有点冗长,但是选择了这种方式,所以希望它变得清晰。如果您还想查看尚未赢得任何比赛的玩家,请将JOIN更改为LEFT JOIN

编辑:此SQL假定Winner是对Players表的引用,并不总是1或2。

答案 1 :(得分:0)

添加说明:我刚刚意识到这是关于PostgreSQL。出于某种原因我认为这是MySQL。我没有使用PostgreSQL的经验,但这是标准的SQL,适用于MySQL,Microsoft SQL服务器和Oracle,所以我希望它也适用于PostgreSQL。)

如果Winner是外键,那么它很简单:

select winner, count(*) from Matches group by winner order by 2 desc

如果Winner总是12(意味着Player1Player2获得了相应的奖励)那么它会变得更加冗长:

select
    case when winner=1 then Player1 else Player2 end,
    count(*)
from Matches
group by case when winner=1 then Player1 else Player2 end
order by 2 desc

为了使查询更有用,您可能也想要包含该名称。它比执行第二个查询然后尝试自己匹配更容易(也更快)。以下是修改:

如果Winner是外键,那很简单:

select
    a.winner, b.name, count(*)
from
    Matches a
    join Players b on (a.winner=b.p_id)
group by
    a.winner, b.name
order by 2 desc

如果Winner12,那么......我会去寻找子查询,只是为了展示另一种方法(你也可以像上面那样做) ):

select
    a.id,
    b.name,
    a.count
from
   (select
        case when winner=1 then Player1 else Player2 end id,
        count(*) count,
    from Matches
    group by case when winner=1 then Player1 else Player2 end
   ) a,
   join Players b on (a.id=b.p_id)
order by a.count desc