具有隐私条件检查的查询中的mysql查询

时间:2012-08-13 04:11:24

标签: php mysql

我有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

有一个搜索字段。当登录用户在表“帖子”中搜索“关键字”时,我想省略那些将其隐私设置为“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

因此对于关键字“牛顿”, 如果userA正在搜索,则应返回“posts”中的2,3,4行。 如果userD正在搜索,则只返回“posts”中的第1,3和4行,

基于隐私和以下内容 编辑:标记以备将来搜索:mySql中WHERE子句中的IF条件

3 个答案:

答案 0 :(得分: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. 后面的成员的帖子
  4. 最后,会员本人的帖子。

  5. 修改

    此查询使用原始标识符:

    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;
    

答案 1 :(得分: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;

请参阅:A Visual Explanation of SQL Joins

答案 2 :(得分: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