通过一个例子最容易解释。
父亲有赢得比赛的孩子。
一个父亲的后代中有多少人赢得了一场比赛,一个父亲的后代总共赢得了多少场比赛。(赢家和赢家)
我可以很容易地计算出获胜的总数,但有时一个孩子赢了不止一场比赛,所以要想计算出胜利者,我只需要一个总数,如果孩子赢了,而不是每次都赢了。
在下面从查询中提取的内容中,我无法使用Distinct,因此这不起作用
SUM(CASE WHEN r.finish = '1' AND DISTINCT h.runnersid THEN 1 ELSE 0 END ) AS winners,
这也行不通
SUM(SELECT DISTINCT r.runnersid FROM runs r WHERE r.finish='1') AS winners
当我需要找到赢钱的总数时,这个方法就行了。
SUM(CASE WHEN r.finish = '1' THEN 1 ELSE 0 END ) AS wins,
这里有一个sqlfiddlehttp://sqlfiddle.com/#!2/e9a81/1
最佳答案
让我们一步一步来。
你有两条信息要找:谁赢了一场比赛,他们有多少场比赛。
取第一个,你可以选择一个不同的runnersid,在那里他们有一个第一名完成:
SELECT DISTINCT runnersid
FROM runs
WHERE finish = 1;
对于第二个,您可以选择每个runnersid,其中他们有一个第一名完成,计数返回的行数,并按runnersid分组,以获得每个的总胜利:
SELECT runnersid, COUNT(*) AS numWins
FROM runs
WHERE finish = 1
GROUP BY runnersid;
第二个其实有你想要的一切。您不需要对第一个查询执行任何操作,但我使用它来帮助演示我在尝试完成此类任务时所采取的思维过程。
下面是SQL Fiddle示例。
编辑
正如你所看到的,你并不真的需要这笔钱。因为finish代表了比赛中的一个位置,所以您不想对该值求和,但要计算获胜的次数。
编辑2
基于操作要求的附加编辑。上面的内容与OP的需求不匹配,但我把它留作以后读者的参考。据我现在的理解,OP真正需要的是每个父亲有多少孩子参加过一场比赛。我将再次一步一步地解释我的思维过程。
首先,我写了一个简单的查询,把所有获胜的父子对都拉过来。我可以使用GROUP BY来获得不同的获胜对:
SELECT father, name
FROM runs
WHERE finish = 1
GROUP BY father, name;
完成后,我使用它是一个子查询和COUNT(*)函数来获取每个父亲的获奖人数(这意味着我必须按父亲分组):
SELECT father, COUNT(*) AS numWinningChildren
FROM(SELECT father, name
FROM runs
WHERE finish = 1
GROUP BY father, name) t
GROUP BY father;
如果你只需要有孩子的父亲,你就完了。如果您想看到所有父亲,我将编写一个查询来选择所有父亲,将其与上面的结果集结合起来,并将
numWinningChildren
为空的任何值替换为0。我把那部分留给你来挑战一下自己。另外,因为SQL Fiddle目前已经关闭,我无法测试我的想法,但我能够成功地测试上面的那些。