3

我有表“权限”

| user_id | object_id | readable | writable |

我需要通过以下规则确定当前user_id是否可以访问给定的object_id :

  • 如果object_id根本没有记录,则返回 true
  • 如果object_id有记录但user_id不同,而给定user_id没有记录,则返回 false
  • 如果给定user_idobject_id有记录,则再次检查提供的可读和可写条件

我不确定是否可以构建不涉及嵌套查询的 SQL 查询,现在我提出了

select (
    select count(*) 
    from permission 
    where 
        object_id = 123456
    ) == 0 OR (
        select readable=true, writable=false 
        from permission 
        where user_id=1 and object_id=123456
    )

有没有更优雅的解决方案?

谢谢!

4

3 回答 3

1

尝试:

SELECT count(*) as total_count, --count of permission records for object
       bool_or(user_id = 1 AND readable) as user_readable, -- user has read permission, null if no permission record
       bool_or(user_id = 1 AND writable) as user_writable, -- user has write permission, null if no permission record
FROM permission
WHERE object_id = 123456

然后从此查询构建您的逻辑案例,例如:

SELECT total_count = 0 OR user_readable as readable,
       total_count = 0 OR user_writable as writable
FROM (first select here)
于 2012-12-20T14:06:51.257 回答
0

你可以这样做:

select 
  case 
    when (not exists (select object_id from permissions where object_id=123456)) then true
    when (not exists (select * from permissions where object_id=123456 and id=1)) then false
    else <check your conditions here> 
  end;

araqnid 的查询效率略低,但可读性更强。

于 2012-12-20T13:40:01.070 回答
0
select true as readable, true as writable
where not exists (select 1 permission where object_id = 123456)
union all
select readable, writable
from permission
where user_id = 1 and object_id = 123456

请注意,您有不相交的可能性:

  • 对象没有权限
  • 对象存在权限
    • 用户存在权限
    • 用户没有权限

也就是说,如果不存在权限,则返回 true。否则返回用户的权限。如果存在该用户但不存在的权限,则不返回任何内容(在这种情况下,您可以使查询显式返回“false,false”,但为什么要浪费精力?)

此外,这假定这(object_id, user_id)permission表的唯一键。

于 2012-12-20T13:40:29.233 回答