我正在处理某些应用程序,我们正在使用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)
对于其他行是真的,或者也许使用此值检查是否缺少行。
答案 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