postgresql :: retrieve row匹配条件的精确条件或行数

时间:2012-12-20 13:18:24

标签: sql postgresql lazy-evaluation

我有表“许可”,如

| user_id | object_id | readable | writable |

我需要查看当前 user_id 是否可以使用以下规则访问给定的 object_id

  • 如果根本没有 object_id 的记录,则返回true
  • 如果有 object_id 的记录,但针对不同的 user_id ,但没有给定 user_id 的记录,则返回false
  • 如果有给定 user_id object_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
    )

有更优雅的解决方案吗?

谢谢!

3 个答案:

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

答案 1 :(得分: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的查询效率稍差,但可能更具可读性。

答案 2 :(得分: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表的唯一键。