1

すべてのツールとCMSが周りにあるので、アプリケーションを作成するのはいつも簡単でした。ORMを使用せずに高度なSQLを使用する必要があるのは初めてですが、探している結果を取得する方法がわかりません。

ユーザーフレンドシステムを作ろうとしています。基本的に、ユーザーは別のユーザーを友達として追加でき、友達のユーザーは受け入れることができます。UsersとUsers_Relationshipsの2つのテーブルがあります。Usersテーブルには明らかなユーザー情報があり、User_Relationshipsテーブルにはrelation_setter(リクエスターユーザーのID)、relation_getter(リクエスターユーザーのID)があり、アクティブです。

問題は、ページにすべての友達(アクティブまたは非アクティブ)を表示する必要があることです。次のクエリが間違っていることは知っていますが、これが私が思いついたものです。

$sql = "SELECT *
        FROM users_relationships
        LEFT JOIN users
        ON users_relationships.relation_setter = users.user_id
        WHERE users_relationships.relation_getter = " . $logged_in_id.
      " OR users_relationships.relation_setter = " . $logged_in_id;

私が必要としているのは、$logged_in_userを持つセッターまたはゲッターとしてリレーションシップテーブルにいるすべてのユーザーです。誰が追加したか、私または彼らに関係なく、友達のすべての人が必要です。各行で取得した「アクティブ」値に基づいて、「リクエスト保留中」と表示されます。

上記のクエリは、非常に複雑な結果をもたらし、多くの重複があり、保留中のリクエストも間違っています。

4

2 に答える 2

2

JOINUsers次のようにもう一度テーブルを作成します。

SELECT 
  us.UserName AS SetterName,
  ug.UserName AS GetteerName,
  ur.Active AS Status,
  ...
FROM users_relationships ur
LEFT JOIN users us ON ur.relation_setter = us.user_id
LEFT JOIN users ug ON ur.relation_getter = ug.user_id 
WHERE $logged_in_id IN(ur.relation_getter, ur.relation_setter);

SQLフィドルデモ


アップデート1

友達のリストを2人のユーザーの名前ではなく、1つのリストとして取得するには、次のようにします。

SELECT 
  us.UserName AS FriendName,
  ur.Active AS Status
FROM 
(
  SELECT relation_setter user_id, active 
  FROM users_relationships
  WHERE relation_getter = $logged_in_id 
  UNION  
  SELECT relation_getter, active 
  FROM users_relationships
  WHERE relation_setter = $logged_in_id 
) AS ur
LEFT JOIN users us ON ur.user_id = us.user_id;

SQLフィドルデモ

これにより、ログインしているユーザーの友達名のリストが表示されます。


アップデート2

このクエリはどのように機能しますか?

ログインした使用のリストは、またはのいずれrelation_setterrelation_getterです。したがって、これら2つを1つの列にまとめるために、2つのクエリを使用してそれぞれを取得しますrelation_setter

  SELECT relation_setter user_id, active 
  FROM users_relationships
  WHERE relation_getter = $logged_in_id 

そして他のためにrelation_getter

  SELECT relation_getter, active 
  FROM users_relationships
  WHERE relation_setter = $logged_in_id 

それから私はUNIONそれらを1つの結果セットとして取得していました:

  SELECT relation_setter user_id, active 
  FROM users_relationships
  WHERE relation_getter = $logged_in_id 
  UNION  
  SELECT relation_getter, active 
  FROM users_relationships
  WHERE relation_setter = $logged_in_id 

このクエリは、2つのクエリからのすべてのデータを2つのフィールドのみuser_idに提供しactiveます。

ご了承ください:

  • UNIONは暗黙的に個別の行を選択し、重複する行を削除しますが、UNION ALLそれらの重複する行は保持します。

  • 2つの結合された結果セットには、最初の選択で指定された列の名前が含まれます。このクエリでは、2番目の選択には、最初のクエリで定義されているためrelation_getter、この列からの値が下にあるという名前の最初の列があります。userid

次に、この2つの結合されたクエリをサブクエリ内に囲み、Usersテーブルと結合しました。これで完了です:)

于 2013-02-07T06:39:18.477 に答える
0
$sql = "SELECT *
        FROM users_relationships rel
        LEFT outer JOIN users from  ON rel.relation_setter = from.user_id
        LEFT outer JOIN users to ON rel.relation_getter = to.user_id
        WHERE rel.relation_getter in (" . $logged_in_id. "," . $logged_in_id . ")";
于 2013-02-07T06:46:06.320 に答える