2

私はこの3つのテーブルを持っています:

POST (id, name, id_user, ..)
FRIENDS (id, followerid, followingid, acepted) /* acepted must be 1 to users be considered friends */

OK、ユーザー5からすべての友達の投稿を取得したかったのですが、クエリの作成に多くの問題があります。参加する必要があることはわかっていますが、問題は、現在のユーザー(ID 5)がfolloweridまたはfollowingidである可能性があることです。どうすればわかりますか?

私は次のような何かを試みていました(しかし、無意味でブロックされました):

SELECT posts.*,friends.id 
                    FROM friends LEFT JOIN ON (friends.followerid  = posts.id) OR (friends.following.id = posts.id)

しかし、ONが受け入れるか内部であるかは本当にわかりません。ここでヒントを得ることができますか?ありがとう!

4

3 に答える 3

1

それを行う1つの方法は、組合を利用することです。

SELECT posts.*,friends.id FROM friends LEFT JOIN posts ON 
(friends.followerid  = posts.id) where friends.acepted = 1 and posts.id_user = 5
UNION
SELECT posts.*,friends.id FROM friends LEFT JOIN posts ON 
(friends.following.id = posts.id) where friends.acepted = 1 and posts.id_user = 5
于 2012-06-02T02:00:30.627 に答える
1

句は、ブール式である(単純または複雑な)条件を両方とも受け入れるという点で句に似ONています。演算子はブール演算子であるため、と同様に使用できます。結合条件で任意の方法を使用して、要件を満たす演算子を作成してください。WHEREORONWHEREOR

私はあなたがあなたの質問で基本的に正しい軌道に乗っていると思います。おそらく、現時点で他のことに集中しているという理由だけで、あなたが見逃している可能性のあるいくつかのことを指摘したいと思います。

1つは、結合のタイプです。テーブルには、ユーザーと他friendsのユーザーの間のリンクだけでなく、さまざまなユーザー間の既存のリンクがすべて含まれているはず5です。したがって、左結合(外部結合)で結合すると、ユーザーだけでなく、からすべてのリンクを取得しますがfriends、これおそらく必要なものではありません。もちろん、のような条件で句を追加することもできますが、それは基本的に、その条件のない内部結合と同等です。したがって、代わりに内部結合を使用してください。postsfriends5WHEREfriends.id IS NOT NULL

ただし、もちろん、ユーザー5の友達だけを参加させたいので、あなたのWHERE条項必要になる可能性があるのは条件です。つまり、友達であることが確認された友達を意味すると思います。friends.acepted = 1acepted1

もちろん、5どこかにユーザーの条件もなければなりません。私には、ユーザーの友達だけfriendsを表し、それらも単一の列として表すテーブルを派生させるのが最も簡単だと思います。(つまり、両方のフィルターが、結合の結果セットではなく、派生テーブルに適用されます。)このようにすると、結合条件が単純になるため、友人をテーブルに結合するのが簡単になります。このようなテーブルを導出する方法の1つを次に示します。5posts

SELECT
  id,
  CASE followerid WHEN 5 THEN followingid ELSE followerid END AS friend_id
FROM friends
WHERE acepted = 1
  AND (followerid  = 5 OR followingid = 5)

つまり、このクエリは、ユーザー( )の友達( acepted = 1)であるユーザーIDを取得します。単一のユーザーID列、は、またはのいずれかで構成されます。一方がの場合、もう一方はプルされます。その逆も同様です。5followerid = 5 OR followingid = 5friend_idfolloweridfollowingid5

そして、これが最終的なクエリでこの派生テーブルを使用する方法です。

SELECT
  p.*,
  f.id  /* there's an `id` column in `posts`, so it might be a good idea
           to assign `friends.id` a distinct alias, like `friends_id` */
FROM (
  SELECT
    id,
    CASE followerid WHEN 5 THEN followingid ELSE followerid END AS friend_id
  FROM friends
  WHERE acepted = 1
    AND (followerid  = 5 OR followingid = 5)
) AS f
  INNER JOIN posts AS p ON p.id_user = f.friend_id
于 2012-06-10T11:39:31.557 に答える
0

クエリは機能するはずです:

SELECT posts.*, friends.id 
FROM friends LEFT JOIN
     posts
     ON (friends.followerid  = posts.id) OR
        (friends.following.id = posts.id)

ただし、「on」ステートメントの「or」は通常非効率的です。たとえば、インデックスの使用に大混乱をもたらします。フォロワーとフォロワーがいる場合、このメソッドは投稿ごとに複数の行を生成することに注意してください。

別の定式化は、両方を同じ行に配置することです。

SELECT posts.*, follower.id, following.id 
FROM posts left outer join
     friends follower
     ON follower.followerid = posts.id left outer join
     friends following
     on following.followingid = posts.id
where follower.id = 5 or following.id = 5
于 2012-06-02T02:03:41.513 に答える