0

这可能是一个稍微令人困惑的问题。我有一个用户帖子表,其中有一列权限确定谁可以查看帖子:0 = 公开,1 = 仅限订阅者,2 = 仅限联系人。

我有另一个表“订阅”,其中包含 Subscriber_ID 和 Subscribed_to_ID 列,还有另一个表“联系人”,其中包含 User1_ID 和 User2_ID 列。

我对复杂的 MySQL 查询没有太多经验,我通常只需要基本查询,但这是我想要做的:

我正在寻找一种在这些条件下从帖子表中选择帖子的方法:

  1. 如果用户既不是订阅者也不是帖子作者的联系人,则只返回公共帖子(Permission 为 0 的帖子)
  2. 如果用户订阅了帖子作者,则返回具有 0 或 1 权限的帖子
  3. 如果用户是联系人(自动订阅),则返回具有 0、1 或 2 权限值的帖子。

我知道语法不正确,但这是否是一个很好的方法?另外,我通常一次只处理一张桌子,所以我很困惑,我需要加入这三张桌子吗?

SELECT user_id, 
       * 
FROM   posts 
WHERE  privacy < IF (user_id IN(SELECT * 
                                FROM   contacts 
                                WHERE  user1_id = 'TestUser' 
                                        OR user2_id = 'TestUser'), 2, 
                 IF ( 
                                  user_id IN (SELECT subscribed_to_id 
                                              FROM   subscriptions 
                                              WHERE  subscriber_id = 'TestUser') 
                 , 
                 1, 0) 
                        ) 

再说一次,我知道我还很遥远,但我想学习一些比我习惯的基本知识更复杂的 MySQL,所以如果有人能给我一些关于如何改进这个查询的建议,我一定会很感激!

4

4 回答 4

0

你真的需要加入这些表。而且,在 MySQL 上不使用条件确实更容易,比 PHP 更好。

如果我需要这样做,我会这样做。

您选择帖子,加入规则,加入订阅者,加入用户,然后使用 PHP 显示或不显示消息。

你的查询有点奇怪。

连接表并不复杂。

于 2013-01-24T21:21:13.290 回答
0

如果我正确理解这一点,我相信您的第一个要求可能是这样的:

SELECT user_id, *
FROM posts P
LEFT OUTER JOIN subscriptions S
ON P.user_id = S.Subscribed_To_ID
LEFT OUTER JOIN contacts C
ON C.User1_ID = P.user_id
WHERE S.Subscribed_To_ID IS NULL
AND C.User1_ID IS NULL
AND P.Privacy = 0

然后你能再创建两个 SELECT 语句并将它们联合起来吗?

于 2013-01-24T21:22:13.403 回答
0

你应该只使用一个函数来简化你的生活。无论如何,您都在进行全表查询,因此优化不是问题。

SELECT *
FROM   posts 
WHERE  privacy <= TestPrivacy('TestUser')

CREATE FUNCTION TestPrivacy(CurrentUser VARCHAR(MAX))
BEGIN
DECLARE returnValue INT
   IF ((SELECT COUNT(*) 
      FROM   contacts 
      WHERE  user1_id = CurrentUser
      OR user2_id = CurrentUser) > 0)
   BEGIN
      ReturnValue = 2
   END
   ELSE
   BEGIN
      IF ((SELECT COUNT(*) 
          FROM   subscriptions 
          WHERE  subscriber_id = CurrentUser) > 0) THEN
      BEGIN
         returnValue = 1
      END
      ELSE
      BEGIN
         returnValue = 0
      END
   END

   RETURN returnValue
END
于 2013-01-24T21:24:40.907 回答
0

尝试这个:

select *
  from posts
 where (privacy = 0) /* public */
    or ( /* suscribers */
            (privacy = 1) 
        and (exists (select 1 
                       from subscriptions 
                      where subscriptions.suscriber_id = 'currentuser' 
                        and subscriptions.Subscribed_to_ID = posts.author_id)
            )
       )
    or ( /* contacts: if the user is a contact, doesn't matter the privacy */ 
        exists (select 1
                  from contacts
                 where (contacts.User1_ID = 'currentuser' and contacts.user2_ID = posts.author_id)
                    or (contacts.user2_ID = 'currentuser' and contacts.user1_id = posts.author_id)
        )
       )

我是根据这些假设做的:

  • 您想选择用户可以从所有作者那里看到的所有帖子。
  • 您的帖子表有一个名为 author_id 的列,其中包含帖子作者的 user_id。
  • 查看者的 user_id 是已知的,并在查询中显示为“currentuser”
  • 您的联系人表每个联系人对仅包含一行,因此 where 子句中的双重比较

查询是在浏览器中编写的,您可能会遇到语法错误或其他小问题。查看缩进以检查正确的括号配对。

于 2013-01-24T21:43:53.227 回答