mySQL SELECT帮助。 IF还是EXISTS?

时间:2015-02-23 16:50:22

标签: mysql

我有这个数据库结构

* user
user_id
name

* client
client_id
name

* user_client
user_client_id
user_id
client_id

* message
message_id
client_id
description

如果user_client上有条目,则用户的权限仅限于为其表中的ID列出的特定客户端。如果没有条目,则用户可以访问任何客户端。

如何只选择用户可以阅读的消息?

我试图在WHERE子句上执行IF以检查user_client表上是否有任何条目,但我不知道从哪里开始。如果user_client上没有条目,或者只有client_id表上指定的user_client消息

,则需要从任何客户端选择所有消息

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

这样做的一种方法是使用两个不同的查询来创建一组用户可以根据您的需求查看和过滤的消息;这样的事情应该有效:

select * from (
    select u.user_id, u.name, c.name client, m.message_id, m.description 
    from user u
    join user_client uc on u.user_id = uc.user_id
    join client c on uc.client_id = c.client_id
    join message m on c.client_id = m.client_id
    union all
    select u.user_id, u.name, c.name client, m.message_id, m.description
    from user u
    cross join client c 
    join message m on c.client_id = m.client_id
    where user_id not in (select user_id from user_client)
) x
where x.user_id = 1;

此处user_client表中的用户仅限于他们有权访问的消息集(union中的第一个集),而user_client表中不存在的用户可以看到所有消息(union中的第二个集) )。

Sample SQL Fiddle

答案 1 :(得分:0)

如果我正确理解您的问题,例如

1)管理用户......他们可以查看所有内容,因为他们在user_client表中没有记录。

2)客户主管......这样一个人的主要责任是特定客户(或多个客户)。因此,用户DOES在user_client表中有记录。如果是这样,那么只允许用户查看他们与之有关联的客户的记录。

select
      m.message_id,
      m.client_id,
      m.description,
      c.name as clientName
   from
      ( select count(*) as HasClients
           from user_client
           where user_id = TheUserYouWant ) ClientCheck,
      message m
         left join user_client uc
            on m.client_id = uc.client_id
           AND uc.user_id = TheUserYouWant
         join client c
            on m.client_id = c.client_id
   where
         ClientCheck.HasClients = 0
      OR NOT uc.user_id IS NULL

查询查看user_client表TWICE。第一次是获取给定用户存在的那些记录的计数,而不管与哪个客户关联。查询将始终返回1行,它将为0(没有这样的记录),或者大于1(无论它们与多少有关联)。

第二个实例是对user_client表的LEFT-JOIN,JUST IN CASE只限于查看自己的客户端消息。

WHERE子句现在出现并说...如果客户端的基础数量为零,那么可以给我所有消息。如果有任何其他值,那么user_client表中的用户ID(左边连接到你想要的CLIENT和USER上的消息)必须存在(通过NOT user_id列的NULL值)。

现在,您可能不希望查询每条消息,因为它可能会随着数据库的增长而变得非常大,但您可以在WHERE子句中添加任何其他条件,例如日期限制和/或客户端有兴趣。

答案 2 :(得分:0)

我建议做两个不同的查询:一个用于超级用户,另一个用于受限用户。然后你可以用UNION加入两个结果。

    SELECT M.message_id,
           M.client_id,
           M.description
      FROM message M
INNER JOIN user_client UC ON (UC.client_id = M.client_id)
INNER JOIN user U ON (UC.user_id = U.id)
     WHERE U.id = :user_id

     UNION

    SELECT M.message_id,
           M.client_id,
           M.description
      FROM message M
     WHERE NOT EXISTS ( 
               SELECT *
                 FROM user_client
                WHERE user_id = :user_id
           )

您可以使用其他查询获得相同的结果,但恕我直言,这个更清晰,更易于维护。

编辑:如果要确保用户存在,则应使用用户表加入第二个查询。

    SELECT M.message_id,
           M.client_id,
           M.description
      FROM message M
      JOIN user U
     WHERE U.id = :user_id
       AND NOT EXISTS ( 
               SELECT *
                 FROM user_client
                WHERE user_id = :user_id
           )