1

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

myMembers
------------------------------------
id | username | privacy
------------------------------------
1  | userA    | 0
2  | userB    | 1
3  | userC    | 0
4  | userD    | 1

following
--------------------------------
id  | user_id  | follower_id
--------------------------------
1   | 2        | 1

posts
-------------------------------------
id  |  userID | username   | statusMsg
--------------------------------------
1   |  4      | userD    | Issac Newton is genius
2   |  2      | userB    | Newton Saw apple
3   |  3      | userC    | Newtonian Physics
4   |  1      | userA    | Calculus came from Sir Newton

検索フィールドがあります。ログインしたユーザーがテーブル「posts」で「keyword」を検索するときに、プライバシーを「1」に設定し、WHEREサーチャーがユーザーBをフォローしていないユーザーの結果を省略したいと思います。

クエリは論理的にこれを行う必要があります。

SELECT * from posts WHERE (match the keyword) 
            AND ( 
                if (poster's privacy (which is set in myMembers)==1){
                    if (seacher is following poster){
                        select this post
                    }
                }
                   else { select this post
                }
             )
                   LIMIT results to 5 rows

したがって、キーワード「Newton」の場合、userAが検索している場合は、「posts」の行2、3、4が返されます。userDが検索している場合、「posts」の行1、3、4のみが返されます。

プライバシーに基づき、次の編集:将来の検索のためのタグ付け:mySqlのWHERE句内のIF条件

4

3 に答える 3

1

このクエリを試してください(SQL Fiddleでも):

SELECT p.id, p.user_id, m.username, m.privacy,
       searcher.username "Searcher", p.status_msg
  FROM posts p
  JOIN members m ON m.id = p.user_id
  LEFT JOIN following f ON p.user_id = f.user_id
  JOIN members searcher ON searcher.username = 'userA'
 WHERE (m.privacy = 0 OR (m.privacy = 1 AND f.follower_id = searcher.id)
                      OR m.id = searcher.id)
   AND p.status_msg LIKE '%New%'
 ORDER BY p.id
 LIMIT 5;

冗長であるため、テーブルusernameからフィールドを削除しました。postsまた、テーブルと列の名前を少し異なるため、クエリでスキーマの外観を変更する必要がある場合があります。

句の最初の行はWHEREあなたが探しているものであり、次の順序で投稿を選択します。

  1. プライバシーのないメンバーからの最初の投稿。
  2. 次に、現在のメンバーが続くメンバーからの投稿searcher
  3. 最後に、メンバー自身の投稿。

編集:

このクエリは元の識別子を使用しています。

SELECT p.id, p.`userID`, m.username, m.privacy,
       searcher.username "Searcher", p.`statusMsg`
  FROM posts p
  JOIN `myMembers` m ON m.id = p.`userID`
  LEFT JOIN following f ON p.`userID` = f.user_id
  JOIN `myMembers` searcher ON searcher.username = 'userD'
 WHERE (m.privacy = 0 OR f.follower_id = searcher.id OR m.id = searcher.id)
   AND p.`statusMsg` LIKE '%New%'
 ORDER BY p.id
 LIMIT 5;

編集2:

テーブルからユーザーのフォロワーが複数いる場合に重複を避けるためにposts、結合とフィルタリングの条件を次のように変更する必要があります(SQL Fiddleの場合)。

SELECT p.id, p.user_id, m.username, m.privacy,
       searcher.username "Searcher", p.status_msg
  FROM posts p
  JOIN members m ON m.id = p.user_id
  JOIN members searcher ON searcher.username = 'userC'
  LEFT JOIN following f ON p.user_id = f.user_id
   AND follower_id = searcher.id
 WHERE (m.privacy = 0 OR (m.privacy = 1 AND f.id IS NOT NULL)
                      OR m.id = searcher.id)  
 ORDER BY p.id
 LIMIT 5;
于 2012-08-13T11:14:23.710 に答える
0

これを試して:

SELECT a.*
FROM posts a
     LEFT JOIN (SELECT user_id
                FROM following a1
                     INNER JOIN myMembers b1
                       ON a1.follower_id = b1.id
                  WHERE a1.follower_id = 1 AND
                        b1.privacy = 1
                ) b
                ON a.userID = b.user_id AND
WHERE a.statusMsg LIKE '%search%' AND
      b.user_id IS NULL
LIMIT 5;

またはサブクエリなしのより良いアプローチ:

SELECT a.*
FROM posts a
     LEFT JOIN myMembers b
         ON a.userID = b.id AND
            b.privacy = 1
     LEFT JOIN following c
         ON a.userID = c.user_id AND
            c.follower_id = 1
WHERE a.statusMsg LIKE '%search%' AND
      b.id IS NULL AND
      c.user_id IS NULL
LIMIT 5;

参照:SQL結合の視覚的説明

于 2012-08-13T04:23:02.953 に答える
0

次のことを試してください。

SET @my_user_id= 1;

SELECT * FROM posts p
INNER JOIN myMembers m ON p.user_id= m.id  
WHERE statusMsg LIKE '%'
AND privacy=0
AND user_id IN (SELECT follower_id FROM following f WHERE f.user_id=@my_user_id)
LIMIT 5
于 2012-08-13T05:11:26.077 に答える