计算SQL中多列的值

时间:2015-03-26 18:18:35

标签: mysql sql

对于体育锦标赛,人们在另外一组2名球员中成对比赛时,我想输出一个特定球员面对的每个对手的名单,以及比赛中的胜负,抽奖和失利数量特定玩家和对手之间。

例如,如果结果是:

  1. 播放器1&播放器2 2-1播放器3&玩家4
  2. 玩家3&球员1 1-0球员2&玩家4
  3. 播放器2&玩家4 4-2玩家1&球员3
  4. 播放器1&球员4 0-0球员3&玩家2
  5. 我希望播放器1的输出为:

    • 玩家2,W1 D1 L1
    • 玩家3,W1 D1 L0
    • 玩家4,W2 D0 L1

    这已经证明难以实现。 我的数据分为两个表格,一个包含所有玩家(玩家)和一个得分表(分数)的表格。

    玩家拥有PlayerID和PlayerName字段。

    分数有字段Player1,Player2,Player3,Player4和Score,其中每个Player字段可以包含任何PlayerID(因此任何给定的ID可以根据行显示在不同的列中),并且存储分数,如果它少于21,播放器1& 2输了,如果大于21,他们就赢了。

    此查询有什么问题?显然它正在返回0。

    SELECT opponent as opp, COUNT(result='win') as c1, COUNT(result='draw') as c2, COUNT(result='loss') as c3
          FROM (SELECT
                CASE
                    WHEN '$player' IN(Players1.PlayerName, Players2.PlayerName) THEN Players3.PlayerName
                    WHEN '$player' IN(Players3.PlayerName, Players4.PlayerName) THEN Players1.PlayerName
                    ELSE 'NA' 
                    END as opponent,
                CASE
                    WHEN '$player' IN(Players1.PlayerName, Players2.PlayerName) 
                    THEN
                        CASE
                            WHEN Scores.Score > 21 THEN 'win'
                            ELSE 'NA'
                            END as result,
                        CASE
                            WHEN Scores.Score < 21 THEN 'loss'
                            ELSE 'NA'
                            END as result,
                    WHEN '$player' IN(Players3.PlayerName, Players4.PlayerName) 
                    THEN
                        CASE
                            WHEN Scores.Score < 21 THEN 'win'
                            ELSE 'NA'
                            END as result,
                        CASE
                            WHEN Scores.Score > 21 THEN 'loss'
                            ELSE 'NA'
                            END as result,
                    WHEN Scores.Score = 21 THEN 'draw'
                    ELSE 'NA' 
                    END as result,
            FROM Scores
            INNER JOIN Players Players1 ON Scores.Player1=Players1.PlayerID
            INNER JOIN Players Players2 ON Scores.Player2=Players2.PlayerID
            INNER JOIN Players Players3 ON Scores.Player3=Players3.PlayerID
            INNER JOIN Players Players4 ON Scores.Player4=Players4.PlayerID
            WHERE Players1.PlayerName = '$player' OR Players2.PlayerName = '$player' OR Players3.PlayerName = '$player' OR Players4.PlayerName = '$player'
            UNION ALL
            SELECT
                CASE
                    WHEN '$player' IN(Players1.PlayerName, Players2.PlayerName) THEN Players4.PlayerName
                    WHEN '$player' IN(Players3.PlayerName, Players4.PlayerName) THEN Players2.PlayerName
                    ELSE 'NA' 
                    END as opponent,
                CASE
                    WHEN '$player' IN(Players1.PlayerName, Players2.PlayerName) AND Scores.Score > 21 THEN 'win'
                    WHEN '$player' IN(Players1.PlayerName, Players2.PlayerName) AND Scores.Score < 21 THEN 'loss'
                    WHEN '$player' IN(Players3.PlayerName, Players4.PlayerName) AND Scores.Score < 21 THEN 'win'
                    WHEN '$player' IN(Players3.PlayerName, Players4.PlayerName) AND Scores.Score > 21 THEN 'loss'
                    WHEN Scores.Score = 21 THEN 'draw'
                    ELSE 'NA' 
                    END as result,
            FROM Scores
            INNER JOIN Players Players1 ON Scores.Player1=Players1.PlayerID
            INNER JOIN Players Players2 ON Scores.Player2=Players2.PlayerID
            INNER JOIN Players Players3 ON Scores.Player3=Players3.PlayerID
            INNER JOIN Players Players4 ON Scores.Player4=Players4.PlayerID 
            WHERE Players1.PlayerName = '$player' OR Players2.PlayerName = '$player' OR Players3.PlayerName = '$player' OR Players4.PlayerName = '$player'
        ) AS SUBQUERY
        GROUP BY opp
    

1 个答案:

答案 0 :(得分:1)

它不是很漂亮,但由于MySQL缺少Pivot功能,你可以用一个内部查询来解决结果,该查询会分解谁扮演谁以及结果是什么。然后外部查询可以聚合这些结果。类似下面的东西对我有用,但是,再次,不漂亮

select players.name as playerName, 
  opponents.name as opponentName, 
  SUM(CASE WHEN result = 'W'THEN 1 ELSE 0 END) AS win, 
  SUM(CASE WHEN result = 'L'THEN 1 ELSE 0 END) AS lose, 
  SUM(CASE WHEN result = 'D' THEN 1 ELSE 0 END) AS draw 
from  (
    select player1 as player, player3 as opponent, score, CASE WHEN score > 21 THEN 'W' WHEN score < 21 THEN 'L' ELSE 'D' END as result
    from scores
    union all
    select player1 as player, player4 as opponent, score, CASE WHEN score > 21 THEN 'W' WHEN score < 21 THEN 'L' ELSE 'D' END as result
    from scores
    union all
    select player2 as player, player3 as opponent, score, CASE WHEN score > 21 THEN 'W' WHEN score < 21 THEN 'L' ELSE 'D' END as result
    from scores
    union all
    select player2 as player, player4 as opponent, score, CASE WHEN score > 21 THEN 'W' WHEN score < 21 THEN 'L' ELSE 'D' END as result
    from scores
    -- now reverse result because opponents are being slotted into the player position
    union all
    select player3 as player, player1 as opponent, score, CASE WHEN score > 21 THEN 'L' WHEN score < 21 THEN 'W' ELSE 'D' END as result
    from scores
    union all
    select player4 as player, player1 as opponent, score, CASE WHEN score > 21 THEN 'L' WHEN score < 21 THEN 'W' ELSE 'D' END as result
    from scores
    union all
    select player3 as player, player2 as opponent, score, CASE WHEN score > 21 THEN 'L' WHEN score < 21 THEN 'W' ELSE 'D' END as result
    from scores
    union all
    select player4 as player, player2 as opponent, score, CASE WHEN score > 21 THEN 'L' WHEN score < 21 THEN 'W' ELSE 'D' END as result
    from scores
) resultsByPlayer
inner join players on players.playerId = resultsByPlayer.player
inner join players as opponents on opponents.playerId = resultsByPlayer.opponent
group by players.playerId, opponents.playerId