0

訪問者が「バトル」を作成し、ビデオをアップロードしてこれらの戦いで競うことができる Web サイトを持っています。

次の mySQL クエリは、データベース内のすべての「戦闘」の詳細を取得しようとしています。

私が抱えている問題は、「バトル クリエーター」が同じバトルに 2 つの「ビデオ」をアップロードした場合、重複したバトルが出力されることです。

ビデオテーブルに同じ Battle_id の下に 2 つのエントリがある場合でも、各戦闘に対して 1 つの値のみを出力するクエリを作成するにはどうすればよいですか?

ありがとう!

SELECT * from Battles, Player, Video 
WHERE (Battles.battle_creator = Player.player_id 
AND Battles.battle_id = Video.battle_id 
AND Video.player_id = Battles.battle_creator) 
ORDER BY Battles.battle_date DESC;
4

4 に答える 4

1

1 人のユーザーが複数の動画を 1 つのバトルに割り当てた場合、1 回のクエリで求めている情報を取得する方法はありません。

戦闘用のすべてのデータを取得する最善の方法は、クエリを 2 つのサブクエリに分割することです。

SELECT * from Battles, Player 
WHERE Battles.battle_creator = Player.player_id
ORDER BY Battles.battle_date DESC;

...その後:

SELECT * from Video 
ORDER BY Battles.battle_date DESC, Player.player_id;

最初のクエリでは、戦闘ごとに 1 つの行が返されます。2 つ目は、すべての戦闘のすべてのビデオを提供し、反復することができます。

スケーリングの観点からは、JOIN を完全に回避する方がよいため、余分な作業はそれだけの価値があります。

于 2012-10-20T20:53:21.517 に答える
0

クエリに LIMIT 1 句を追加して最初の結果のみを取得するか、次のような DISTINCT 句を使用できます

SELECT DISTINCT *
FROM ...

ただし、複数のテーブルをクエリする場合は「SELECT *」を使用しないでください。具体的には、「SELECT table.*」または「SELECT table.field1, table.field2, ...」を使用してください。

于 2012-10-20T20:45:05.780 に答える
0

クエリが次の理由で、「正確に」それを行うことはできません。

SELECT * from Battles, Player, Video  ...

は暗黙のうちにすべてのビデオを要求しています。ですから、最初に自問する必要があります。必要なビデオを 1 つ選択するにはどうすればよいでしょうか。

1 つのビデオだけが必要な場合はLIMIT 1、クエリに追加して、それで完了です。ORDER BYvideo_date の前に ASC または DESC を指定しLIMITて、最も古いビデオまたは最新のビデオを取得します。

それ以外の場合は、次のようにする必要があります。

SELECT * from Battles
    JOIN Player ON (Battles.battle_creator = Player.player_id)
    JOIN Video  ON (Battles.battle_id = Video.battle_id 
                    AND Video.player_id = Battles.battle_creator)
WHERE Video.video_id = (SELECT MIN(video_id) FROM Video AS Video2 WHERE
               Battles.battle_id = Video2.battle_id 
               AND Video2.player_id = Battles.battle_creator)
ORDER BY Battles.battle_date DESC;

上記の例では、「動画選択基準」として「video_id が最小の動画」を使用しました。(Video.video_id) にインデックスを付けたいと思うでしょう。

CREATE INDEX video_ndx ON Video(player_id, battle_id, video_id);
于 2012-10-20T21:02:57.410 に答える
-1

Ninsuo のコメントが指摘しているように、これを制御する適切な方法は、ORDER BY 句の後に LIMIT 1 を指定することです。

重複なしで、テーブル全体が必要な場合、これは機能しません。返されたデータに対していくつかの比較チェックを実行するか、SELECT DISTINCT を使用することを検討してください。

于 2012-10-20T20:43:34.310 に答える