1

PHPBB3 データベースを開き、関連するゲーム サーバーのホワイトリストとして使用されるフォーラムのすべての Minecraft ユーザー名のリストを取得する PHP ファイルを作成しようとしています。ユーザー名 (urbb_profile_fields_data.pf_mcusername) は、次のようにフィルタリングする必要があります: ユーザー名が null ではない、空白でない、禁止されていない (ID が urbb_banlist.ban_userid 内の ID と一致しない) およびアクティブ化されている (urbb_users.user_inactive_reason が 0 である) )。

私のSQLの知識は確かに非常に貧弱ですが、これを完全に機能させて実装しました:

SELECT urbb_profile_fields_data.pf_mcusername, urbb_profile_fields_data.user_id, urbb_banlist.ban_userid FROM urbb_profile_fields_data, urbb_banlist WHERE ((pf_mcusername IS NOT NULL) AND (pf_mcusername <> '')) AND ban_userid != urbb_profile_fields_data.user_id

ただし、使用しようとすると: urbb_users.user_inactive_reasonwithinSELECT およびurbb.userswithin FROM、SQL は 7000 を超える結果を取得し、ループを繰り返しているように見えます。これは、 に入るとすぐに発生urbb_usersFROMます。

私は JOIN にあまり慣れていないため (いくつかのチュートリアルを読んだことがあります)、ここで見逃しているものがあることは間違いないので、誰かがここで助けてくれることを願っています!

ありがとう。

4

1 に答える 1

1

クエリの実装に重大な問題があります。他のテーブルが関係していなくても、実際には機能しないはずです。

SQLで「FROM A、B」が意味するのは、「AとBの両方のすべてのフィールドを持ち、その行がすべてAとBの両方から可能な組み合わせである別のテーブルを作成し、そこから選択する」ことです。したがって、各テーブルに 4 行あるとします。結果のテーブルには 16 行あります。不要な行をフィルタリングするには、条件"WHERE A.user_id = B.user_id"を使用します。そうすれば、結果のテーブルには、両方の部分が実際に同じユーザーに対応する行のみが含まれます。

ただし、クエリには「WHERE A.user_id != B.user_id」があり、両方の部分が一致しないすべての行のループ セットを返す必要があります。禁止リストにプレイヤーが 1 人しかいない場合は機能しますが、少なくとも 2 人いる場合は、ループするだけでなく、禁止されたプレイヤーも結果のリストに入れられます。また、禁止されたユーザーがいない場合、クエリの結果は空になります。

適切なクエリは次のようになります。

SELECT A.username, B.user_id FROM A LEFT JOIN B ON A.user_id = B.banned_id
WHERE B.banned_id IS NULL

基本的に、テーブル B に一致しないテーブル A の行を探します。他のテーブルをクエリに追加するには、次のようにそれらを接続する必要があります。

SELECT A.username, B.user_id FROM A LEFT JOIN B ON A.user_id = B.banned_id
LEFT JOIN C ON A.user_id = C.user_id WHERE B.banned_id IS NULL

それが役に立てば幸い...

于 2012-12-24T05:46:26.910 に答える