3

昨日の就職の面接でこの質問をされましたが、かなりストレートに見えましたが、理解できず、それについて考えて一晩中起きていました.

システムは、scrabble リーグに関するデータを記録します。メンバー テーブル、games テーブル、joining member_games テーブルがあります。

members: member_id, name : pk(member_id)
member_games: game_id, member_id, score : pk(game_id, member_id)
games: game_id, location, date : pk(game_id)

members
1, mick
2, keith
3, charlie

member_games
1, 1, 50
1, 2, 60
2, 1, 45
2, 3, 105
3, 1, 30
3, 3, 120

game
1, london, 2012-12-01
2, richmond, 2012-12-02
3, leeds, 2012-12-03

member_id= 1の勝利数を調べる SQL クエリをどのように作成しますか?

4

4 に答える 4

4

の勝利数を検索するクエリmember_id = 1

SELECT COUNT(1) "No. of Wins"
  FROM (SELECT game_id, member_id, score
          FROM member_games b
         WHERE score =
               (SELECT max(score) from member_games WHERE game_id = b.game_id)) A
 WHERE member_id = 1;

このSQLFiddleを参照してください

于 2013-02-08T04:58:53.247 に答える
2

重要なのは、最初に member_games をグループ化し、最高スコアを取得してから、それを member_games テーブルに結合して member_id を取得することです。

実は、Member_id が 0 ゲームに勝ったことを確認するには、左結合が必要です。

SELECT
    member_games.member_id
    ,COUNT(BestScore.game_id)
FROM member_games
LEFT JOIN
    (
    SELECT game_id, MAX(score) AS HighestScore FROM member_games GROUP BY Game_ID
    ) BestScore ON member_games.Score = BestScore.HighestScore
AND member_games.game_id = BestScore.game_id
WHERE member_games.member_id = 1
GROUP BY member_games.member_id;

ここでは、MySQLとしてSQL Fiddleにあります

このソリューションは引き分けを勝利としてカウントしますが、どの SQL サーバーでも機能するはずです。Rank 関数は、Microsoft SQL Server 2005 以降で使用できます。

完全を期すために、引き分けを勝利としてカウントしない、より複雑なクエリを次に示します。

SELECT
    member_games.member_id
    ,COUNT(BestScore.game_id)
FROM member_games
LEFT JOIN
    (
    SELECT member_games.game_id, HighestScore
    FROM member_games
    LEFT JOIN
        (
          SELECT game_id, MAX(score) AS HighestScore FROM member_games GROUP BY Game_ID
        ) BestScore ON member_games.Score = BestScore.HighestScore
        AND member_games.game_id = BestScore.game_id
        GROUP BY game_id, HighestScore
        HAVING count(1) = 1
    ) BestScore ON member_games.Score = BestScore.HighestScore
WHERE member_games.member_id = 1
GROUP BY member_games.member_id;

MySQL としてのSQL Fiddleでの損失としての結び付き

于 2013-02-08T04:58:13.943 に答える
1

これでうまくいくはずです(SQL Server構文)

SELECT member_id
      ,COUNT(*) Wins
FROM   (
       SELECT member_id
             ,RANK() OVER (PARTITION BY Game_Id ORDER BY score DESC) Position
       FROM  member_games
       ) Positions
WHERE Position=1
      AND
      member_id=1
GROUP BY member_id

RANK()Scrabble で可能な (可能性が低い場合) 同点の可能性が考慮されます。ROW_NUMBER()引き分けが不可能なゲームでは、パフォーマンスがわずかに向上する可能性があります。

この方法は、すべての配置を次のように表示するように簡単に拡張できます。

SELECT member_id
      ,Position
      ,COUNT(*) Games
FROM   (
       SELECT member_id
             ,RANK() OVER (PARTITION BY Game_Id ORDER BY score DESC) Position
       FROM  member_games
       ) Positions
WHERE member_id=1
GROUP BY member_id
        ,Position

このSQLフィドルを参照してください

于 2013-02-08T04:56:50.470 に答える
1

次のクエリは、member_id 1 の勝利数を示します。

select count(*) as number_of_wins
    from member_games as mg1
    where member_id = 1
    and not exists (select 1
        from member_games as mg2
        where mg2.game_id = mg1.game_id
        and mg2.member_id <> mg1.member_id
        and mg2.score >= mg1.score);

次のクエリは、メンバーのリストとそれぞれの勝利数を示します。

select m.*,
    (select count(*) from member_games as mg1
        where member_id = m.member_id
        and not exists (select 1
            from member_games as mg2
            where mg2.game_id = mg1.game_id
            and mg2.member_id <> mg1.member_id
            and mg2.score >= mg1.score)
    ) as number_of_wins
    from members as m;

これらのクエリは、1 位の引き分けを勝利とは見なしません。

MySQL SQL Fiddle デモSQL Server SQL Fiddle デモを作成しました。

于 2013-02-08T05:04:52.663 に答える