1

我为此使用 MS Access

我正在制作有关 UFC 比赛的访问数据库。我有一个战斗时间表表,其中包含每场战斗的每个战士的 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 Schools 上找到了这个,但我不知道这是否适合使用或如何使用。

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

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

4

2 回答 2

3

其实没那么难。您需要逐步建立查询:

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这两个查询。
  • 并非每个战士都赢得了一场战斗,因此并非第一个查询中的所有战士都出现在第二个查询中。
  • 这就是为什么我们需要做 a 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
于 2013-09-01T22:28:42.990 回答
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,您可以使用external 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
于 2013-08-31T20:15:58.750 回答