Postgresql查询结果依赖于同一个表的几行

时间:2015-12-21 14:22:15

标签: postgresql

我正在处理某些应用程序,我们正在使用postgres作为我们的数据库。我根本没有很多SQL经验,现在我遇到了一个问题,我无法找到答案。
所以这是一个问题:
我们将隐私设置存储在单独的表中,每行数据的可访问性取决于此隐私表的几行 隐私表的基本结构是:

entityId | entityType | privacyId | privacyType | allow | deletedAt
-------------------------------------------------------------------
5        | user       |  6        |  user       |  f    |          //example entry
5        | user       |  1        |  user_all   |  t    | 

用两个词来说,这个设置意味着,用户id5允许访问除了用户id6之外的所有人的数据。 所以我通过查询获得可用的数据,如:

SELECT <some_relevant_fields> FROM <table>
JOIN <join> 
WHERE 
  (privacy."privacyId"=6 AND privacy."privacyType"='user' AND privacy.allow=true)
  OR (
    (privacy."privacyType"='user_all' AND privacy."deletedAt" IS NOT NULL)
    AND
    (privacy."privacyType"='user' AND privacy."privacyId"=6 AND privacy.allow!=false)
  );

我知道这种形式的查询不正确,但我想让你知道我想要实现的目标 因此,它必须检查字段的类型/ ID和allow=true,或者检查user_all是否已删除(deletedAt字段为空)并且没有字段限制访问,其中allow = false给这个用户。
但似乎postgres链接所有表达式,因此它在表达式结束时用privacy."privacyType"='user_all'覆盖'user',并且不返回任何结果,或者即使用户&#34;阻止&#34;也返回数据,因为'user_all'存在。 如果AND表达式对于2个不同的行为真,有没有办法写WHERE子句来返回结果,例如在上面的代码中:(privacy."privacyType"='user_all' AND privacy."deletedAt" IS NOT NULL)对于一行是真的而且(privacy."privacyType"='user' AND privacy."privacyId"=6 AND privacy.allow!=false)对于其他行是真的,或者也许使用此值检查是否缺少行。

2 个答案:

答案 0 :(得分:0)

这是你想要的吗?

select <some_fields> from <table> where
privacyType='user_all' AND deletedAt IS NOT NULL
union
select <some_fields> from <table> where 
privacyType='user' AND privacyId=6 AND allow<>'f'; 

答案 1 :(得分:0)

您自己left join表,并使用where找到哪个元素没有匹配。

SELECT p1.*
FROM privacy p1
LEFT JOIN privacy p2
       ON p1."entityId" = p2."entityId"
      AND p1."privacyType" = 'user_all' 
      AND p1."deletedAt" IS NULL
      AND p2."privacyType"='user' AND 
      AND p2."privacyId"= 6 
      AND p2.allow!=false
WHERE 
    p2.privacyId IS NOT NULL