如何计算来自不同表的ID的出现次数

时间:2013-08-31 19:47:56

标签: sql database ms-access count

我正在使用MS Access

我正在UFC战斗中建立一个访问数据库。我有一个fightschedule表,每个战斗的每个战斗机的ID和战斗的胜利者。我正在尝试查询列出每个战斗的战斗机,并列出每个战斗机的胜利数量。

这是我的fightSchedule表的一个例子

    ID  Fighter1    Fighter2    Weight Class            Date    Winner
    A   205         215         Light Heavyweight   8/14/2013   205
    B   206         212         Welterweight        8/15/2013   212
    C   207         218         Middleweight        8/14/2013   207
    D   208         209         Heavyweight         8/14/2013   209

因此,例如,我想要一个看起来像这样的查询:

    Fighter        # of Wins
    205             1
    206             0
    207             1
    208             0
    209             1
    212             1
    215             0
    218             0

我根本不知道将要做什么。我知道如何使用count函数,但不知道如何在我的例子中使用它。

我在W3学校找到了这个,但我不知道这是正确的使用方式还是如何使用它。

SELECT column_name, COUNT(column_name)
    FROM table_name
    GROUP BY column_name

任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:2)

通常,您要做的是将列拆分为行。有几种方法可以在不同的RDBMS中执行此操作。
由于您尚未指定RDBMS,因此我将以非常通用的方式开始 - 使用union all来取消列。我认为这个查询可以在任何RDBMS中使用:

select
   Fighter,
   sum(Wins) as Wins
from
(
  select
      Fighter1 as Fighter,
      case when Fighter1 = Winner then 1 else 0 end as Wins
  from fightSchedule
  union all
  select
      Fighter2 as Fighter,
      case when Fighter2 = Winner then 1 else 0 end as Wins
  from fightSchedule
) as a
group by Fighter

sql fiddle demo

另一方面,对于SQL Server,您可以使用outer apply

select
    C.Fighter,
    sum(C.Wins) as Wins
from fightSchedule
    outer apply (
        select Fighter1, case when Fighter1 = Winner then 1 else 0 end
        union all
        select Fighter2, case when Fighter2 = Winner then 1 else 0 end
    ) as C(Fighter, Wins)
group by C.Fighter

答案 1 :(得分:1)

实际上并不那么困难。你需要在婴儿步骤中建立查询:

1)选择所有曾经打过至少一场战斗的战士,但不要多计算那些打过几次战斗的战士:

select distinct fighter1 from
(
    select fighter1 from fightSchedule 
    union select fighter2 from fightSchedule 
)

2)选择实际获胜的战士的胜利次数:
(这基本上是您在W3Schools上找到的查询)

select winner, count(winner) as Wins
from fightSchedule
group by winner

3)结合前两个查询:

  • 我们需要第一个查询中的战士列表以及第二个查询中的胜利列表,因此我们需要JOIN这两个查询。
  • 并非每个战士都赢得了他的一场战斗,所以并非第一次查询中的所有战士都出现在第二次查询中。
  • 这就是我们需要执行LEFT JOIN的原因,这意味着我们从第一个查询中选择所有行,只选择与第二个查询匹配的行 (标准INNER JOIN会过滤掉第一个查询中第二个查询中缺少的所有行)

在MS Access中,有两种方法可以执行第二个查询:

如果将前两个查询保存为Access中的命名查询,则会更容易 然后你可以像第三个查询中的表一样查询它们:

select fighter1 as Fighter, nz(wincount,0) as Wins
from qryFighters
    left join qryWinners
    on qryFighters.fighter1 = qryWinners.winner

(用qry之类的东西为查询名称添加前缀是件好事。我在这个例子中只是强调它们是查询,而不是“常规”表格

如果您不想将查询保存为名为Access的查询,您也可以在一个大的SQL语句中执行它,尽管它更复杂,如果您没有SQL经验,可能会让您感到困惑:

select fighter1 as Fighter, nz(wincount,0) as Wins
from
(
    select distinct fighter1 from
    (
        select fighter1 from fightSchedule 
        union select fighter2 from fightSchedule 
    )
) as fighters
left join
(
    select winner, count(winner) as wincount
    from fightSchedule
    group by winner
) as winners
on fighters.fighter1 = winners.winner