Комплексная сумма с группировкой - PullRequest
3 голосов
/ 22 июня 2010

У меня есть таблица игр с колонками: 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)?А что если мне понадобится сумма очков, только если какой-то игрок выиграл матч?Можно ли это сделать без использования переменных, циклов и т. Д.

Ответы [ 5 ]

3 голосов
/ 22 июня 2010

Я хотел бы реорганизовать данные, возможно:

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

и т. Д.

2 голосов
/ 22 июня 2010
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
1 голос
/ 22 июня 2010

Чтобы ответить на второй вопрос, вы можете изменить ответ Маркуса на это:

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

В зависимости от того, как вы хотите обрабатывать связи, вам необходимо изменить> =.

1 голос
/ 22 июня 2010

Считаются только победные очки:

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
0 голосов
/ 22 июня 2010

Тестовые таблицы:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...