簡體   English   中英

從SQL中的多個列計數值

[英]Counting values from multiple columns in 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

我希望播放器1的輸出為:

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

事實證明,這很難實現。 我的數據分為兩個表,一個是所有玩家的表(Players),一個是分數表(Scores)。

玩家具有字段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

它不是很漂亮,但是由於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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM