通过外键

时间:2015-12-19 14:42:09

标签: sql sqlite

我有3个桌子,比赛,球员和match_player - 第三个允许多对多关系,因为每个玩家有很多比赛,并且比赛由许多球员组成。

CREATE TABLE IF NOT EXISTS match
             (id integer primary key,
             date text,
             winning_side integer)

CREATE TABLE IF NOT EXISTS player
            (id integer primary key,
            name text)

CREATE TABLE IF NOT EXISTS match_player
            (id integer primary key autoincrement,
            match_id integer,
            player_id integer,
            side integer,
            foreign key(match_id) references match(id),
            foreign key(player_id) references player(id))

一边可以是1或0。

我想知道玩家获胜的比例是多少。

我认为这样做的一个好方法是在match_player上使用SELECT语句,然后计算side == winning_side的条目数。但当然,wins_side在一个单独的表格中。

我一直在谷歌搜索如何轻松做到这一点,但无法理解它。

2 个答案:

答案 0 :(得分:1)

select
    mp.player_id,
    min(p.name) as name,
    sum(case when m.winning_side = mp.side then 1 else 0 end) * 100.00
        / count(*) as win_percentage
from
    match m
    inner join match_player mp
        on mp.match_id = m.id
    inner join player p
        on p.id = mp.player_id
group by mp.player_id

如果你真的只对一个玩家感兴趣,那几乎是一回事。它不会伤害任何东西,但你不再需要group by

select
    min(p.name) as name,
    sum(case when m.winning_side = mp.side then 1 else 0 end) * 100.00
        / count(*) as win_percentage
from
    match m
    inner join match_player mp
        on mp.match_id = m.id
    inner join player p
        on p.id = mp.player_id
where mp.player_id = ???

如果您甚至不关心玩家的名字,那么您可以消除其中一个联接:

select
    sum(case when m.winning_side = mp.side then 1 else 0 end) * 100.00
        / count(*) as win_percentage
from
    match m
    inner join match_player mp
        on mp.match_id = m.id
where mp.player_id = ???

我不知道Sqlite如何处理数字,但通常你需要小心确保你的除法不是整数除法。所以你可能不想等到表达式结束时再乘以100.00。

希望这会给你一个良好的开端。

答案 1 :(得分:0)

假设每个匹配在match_player中出现两次(或n次),对于每个玩家一次,则实际上不需要player表。然后,您可以使用avg()来获取所需的值,因为MySQL具有将布尔值视为整数的便捷功能:

select mp.player_id,
       avg(mp.side = m.winning_side) as proportion_winning
from match_player mp join
     match m
     on mp.match_id = m.id
group by mp.player_id;

如果你想要一个0到100之间的值,那么乘以100:

select mp.player_id,
      100 *  avg(mp.side = m.winning_side) as proportion_winning
. . .