2010-06-22 72 views
3

我有表名为游戏与列:Player1Id,Player2Id,Player1Points,Player2Points。与分组的复杂的总和

的样本数据:

Player1Id Player2Id Player1Points Player2Points 
--------- --------- ------------- ------------- 
John   Piter  4     1 
John   Adam   2    10 
Piter  Adam   4     2 

而且我想与点的总和列表每个球员,这样的:

PlayerId Points 
-------- ------ 
John   6 
Piter  5 
Adam  12 

如何才达到,在SQL(SQL Server 2008中) ?如果只有某位球员赢得比赛,我需要总积分 ?它可以不使用变量,循环等?

回答

2
SELECT Player1Id AS PlayerId, SUM(Player1Points) AS Points FROM 
(SELECT Player1Id, Player1Points FROM MyTable 
UNION ALL 
SELECT Player2Id, Player2Points FROM MyTable) t1 
GROUP BY Player1Id 
ORDER BY Player1Id 

产量:

PlayerId  Points 
--------  ------ 
Adam    12 
John    6 
Piter    5 

如果你添加更多的玩家查询将获得更加复杂。最好在不同的行上记录每个玩家的分数。你可以添加一列来指定游戏。

PlayerId Points GameId 
-------- ------ ------ 
John   4  1 
Piter   1  1 
John   2  2 
Adam   10  2 
Piter   4  3 
Adam   2  3 

您的查询将被简单:

SELECT PlayerId, SUM(Points) 
FROM MyTable 
GROUP BY PlayerId 
ORDER BY PlayerId 
+0

这应该是'UNION ALL'(如果约翰在两场比赛中得分3,它只会计算一次) – Quassnoi 2010-06-22 14:31:19

+0

@Quassnoi,修正了,谢谢! – 2010-06-22 14:33:27

3

我会忍不住重新组织数据,也许是:

Gameid Player Score 
    1 John  4 
    2 John  2 
    1 Piter 1 

+0

另外,如果您开始与3名玩家进行游戏,则不必添加列。 + 1用于建议标准化数据。 – HLGEM 2010-06-22 14:42:09

0

测试表:

DECLARE @Table TABLE (Player1Id VARCHAR(17), Player2Id VARCHAR(17), Player1Points INT, Player2Points INT); 
INSERT INTO @Table 
    SELECT 'John', 'Piter', 4, 1 UNION ALL 
    SELECT 'John', 'Adam', 2, 10 UNION ALL 
    SELECT 'Piter', 'Adam', 4, 2; 

总积分:从赢得比赛

WITH CTE (PlayerId, Points) AS (
    SELECT Player1Id, Player1Points FROM @Table 
    UNION ALL 
    SELECT Player2Id, Player2Points FROM @Table 
) 
SELECT PlayerId, SUM(Points) FROM CTE GROUP BY PlayerId; 

总积分:

WITH CTE (PlayerId, Points, Won) AS (
    SELECT Player1Id, Player1Points, CASE WHEN Player1Points > Player2Points THEN 1 ELSE 0 END FROM @Table 
    UNION ALL 
    SELECT Player2Id, Player2Points, CASE WHEN Player2Points > Player1Points THEN 1 ELSE 0 END FROM @Table 
) 
SELECT PlayerId, SUM(Points) FROM CTE WHERE Won = 1 GROUP BY PlayerId; 

差异:

WITH CTE (PlayerId, Points) AS (
    SELECT Player1Id, CASE WHEN Player1Points > Player2Points THEN Player1Points - Player2Points ELSE (Player2Points - Player1Points) * -1 END FROM @Table 
    UNION ALL 
    SELECT Player2Id, CASE WHEN Player2Points > Player1Points THEN Player2Points - Player1Points ELSE (Player1Points - Player2Points) * -1 END FROM @Table 
) 
SELECT PlayerId, SUM(Points) FROM CTE GROUP BY PlayerId; 
1

这只会计算分数的胜利:

SELECT player, SUM(score) AS score 
FROM (
     SELECT player1id AS player, player1points AS score 
     FROM mytable 
     WHERE player1points > player2points 
     UNION ALL 
     SELECT player2id, player2points 
     FROM mytable 
     WHERE player2points > player1points 
     ) q 
GROUP BY 
     player 
1

要回答你的第二个问题,然后你可以改变马库斯的答案是:

SELECT 
    Player1Id, 
    SUM(Player1Points) 
FROM 
(
    SELECT Player1Id, Player1Points FROM MyTable WHERE Player1Points >= Player2Points 
    UNION ALL 
    SELECT Player2Id, Player2Points FROM MyTable WHERE Player2Points >= Player1Points 
) t1 
GROUP BY 
    Player1Id 

根据您想如何处理的关系,你需要改变> =。