sql >> データベース >  >> RDS >> Mysql

結合で正しいカウントを取得する際の問題

    あなたがやろうとしていることへの最も簡単なアプローチは、相関するサブクエリを使用することだと思います。

    したがって、すぐ下の最初の例は、探している結果を返します 。目標とアシストがゼロの行を除外するように簡単に変更できます。

    各サブクエリでteam_id値を使用しますが、示されているように変数またはパラメーターを指定して指定できるため、値を1回指定するだけで済みます。

    set @team_id := 2;
    
    select
        p.id as player_id
        , p.last_name
        , (
            select count(*)
            from goals
            where player_id = p.id
            and team_id = @team_id
        ) as goals
        , (
            select count(*)
            from assists
            inner join goals on assists.goal_id = goals.id
            where assists.player_id = p.id
            and goals.team_id = @team_id
        ) as assists
    from players p
    

    チーム1の場合:

    +----+-----------+-------+---------+
    | id | last_name | Goals | Assists |
    +----+-----------+-------+---------+
    |  1 | Gretzky   |     2 |       1 |
    |  2 | Lemieux   |     0 |       0 |
    |  3 | Messier   |     1 |       1 |
    +----+-----------+-------+---------+
    

    チーム2の場合:

    +----+-----------+-------+---------+
    | id | last_name | Goals | Assists |
    +----+-----------+-------+---------+
    |  1 | Gretzky   |     0 |       0 |
    |  2 | Lemieux   |     1 |       0 |
    |  3 | Messier   |     0 |       0 |
    +----+-----------+-------+---------+
    

    チーム3の場合:

    +----+-----------+-------+---------+
    | id | last_name | Goals | Assists |
    +----+-----------+-------+---------+
    |  1 | Gretzky   |     0 |       1 |
    |  2 | Lemieux   |     0 |       0 |
    |  3 | Messier   |     1 |       0 |
    +----+-----------+-------+---------+
    

    エピローグ

    より少ないサブクエリや集計クエリでこれを実行しようとすると、最初の試行でいくつかの問題が発生します。

    1つの問題は、group byにすべてのフィールドを含めないと、クエリが正しく機能しない可能性があることです。 MySQLは(ほとんど?)他のデータベースのようにそれについてあなたに不満を抱くことはありませんが、節。

    また、アシストテーブルとプレーヤーテーブルの両方のレコードは、ゴールテーブルを介してチームに間接的にのみ関連しているため、両方のゴールで独立したロールアップを取得し、1つのクエリでアシストするのはかなり困難です。

    ある種の例として、これに対する他の初期の回答には、最初のクイックショットを含め、いくつかの問題がありました。

    • プレーヤーがチームのアシストを持っていたが、そのチームの目標がなかった場合、クエリはそのプレーヤーとチームの組み合わせの結果を返すことができませんでした。結果は不完全でした。

    • プレーヤーがチームの目標を持っていても、そのチームのアシストがなかった場合でも、ゼロを返す必要があるときに、クエリはアシストに対して正の数を返します。 結果は、不完全なだけでなく、実際には間違っていました。

    すぐ下はもう少し正しいですが、それでも不完全な解決策です。残念ながら、0ではなくnullを返すことで、プレーヤーにアシストがないかどうかが正しく示されます。

    ただし、プレーヤーにチームの目標がない場合でも、そのプレーヤーとチームの組み合わせに対するアシストは表示されないため、これはまだ部分的な解決策です。

    これは、プレーヤーとチームごとにアシストを集約する仮想テーブルとしてサブクエリを使用します。サブクエリへの左側の外部結合により、目標はあるがアシストがない場合に結果が返されます。

    select
        p.id as player_id
        , p.last_name
        , count(g.game_id) as goals
        , a.assists
    from players p
    inner join goals g on p.id = g.player_id
    left join (
        select
            assists.player_id
            , goals.team_id
            , count(assists.id) as assists
        from assists
        inner join goals on assists.goal_id = goals.id
        group by player_id, team_id, assists.id
    ) a
    on g.player_id = a.player_id and g.team_id = a.team_id
    where g.team_id = 1
    group by player_id, last_name, g.team_id
    

    そのクエリはこれらの結果を返します:

    +----+-----------+-------+---------+
    | id | last_name | Goals | Assists |
    +----+-----------+-------+---------+
    |  1 | Gretzky   |     2 |       1 |
    |  3 | Messier   |     1 |       1 |
    +----+-----------+-------+---------+
    

    チーム2でこれを実行すると、次の結果が得られます。これは、Lemieuxがチーム2のアシストを持っていないことを示していますが、チーム2のアシストもゴールもない他の2人のプレーヤーにはまったく結果を返していません。

    +----+-----------+-------+---------+
    | id | last_name | Goals | Assists |
    +----+-----------+-------+---------+
    |  2 | Lemieux   |     1 |    null |
    +----+-----------+-------+---------+
    

    最後に、チーム3で実行すると、次の結果が得られます。これは、メシエがチーム3のアシストを持っていないことを示しています。しかし、グレツキーはチーム3のアシストを持っていても、持っていないため、行方不明になっています。 目標 チーム3の場合。したがって、ソリューションは完全ではありません。

    +----+-----------+-------+---------+
    | id | last_name | Goals | Assists |
    +----+-----------+-------+---------+
    |  3 | Messier   |     1 |    null |
    +----+-----------+-------+---------+
    



    1. MySQLの大文字と小文字を区別するテーブルの変換

    2. InnoDB:ロックできません./ibdata1エラー:35

    3. カラム側の暗黙的な変換はどれくらいの費用がかかりますか?

    4. 変数がNULLかどうかを確認し、MySQLストアドプロシージャで設定するにはどうすればよいですか?