需要 SQL 查询帮助:如何在同一个表中排除或优先处理 SQL 中的行

问题描述

我遇到的问题

我有一个包含用户、角色、客户端和系统的应用程序。 我有一个名为“policies”的表,其中包含我的应用程序所依赖的 22 个策略/规则。 22 个中的每一个都可以定义为一个或多个级别。 级别可以是:系统、客户端、角色或用户一个系统有 N 个客户端,一个客户端有 N 个角色,一个角色有 N 个用户认情况下,所有 22 个策略都是在系统级别定义的,但它们可以在任何较低级别被覆盖。

请参阅下表作为示例。系统定义了 22 个策略 (system_id)。请注意 policy_1 也是如何在客户端、角色和用户级别设置的(具有相应的 ID)。


            name             |  value   |                level                 
-----------------------------+----------+--------------------------------------
policy_1                     |    1     |                 system_id
policy_2                     |    4     |                 system_id
policy_3                     |    6     |                 system_id

[policies 4 to 21]           |   ...    |                    ...

policy_22                    |    9     |                 role_id
policy_1                     |    2     |                 client_id
policy_1                     |    9     |                 role_id
policy_1                     |    7     |                 user_id
(22 rows)

即使 policy_1 是在系统级别设置的,但在客户端级别设置时,这也是重要的策略值。在角色级别和用户级别设置时再次发生同样的情况。

查询输入

  • system_id、client_id、role_id、user_id

查询输出 22 个策略设置在最低级别。也就是说,策略应该在它们设置的最低级别上进行优先级排序。

我尝试过的事情

  • LEFTJOIN 与 NOT INTO 子句的组合

解决方法

嗯嗯。 . .如果我理解正确,您可以使用 distinct on。关键是过滤和排序:

select distinct on (name) p.*
from policies p
where level = 'system_id' and value = $system_id or
      level = 'client_id' and value = $client_id or
      level = 'role_id' and value = $role_id or
      level = 'user_id' and value = $user_id
order by p.name,(case when level when 'system_id' then 1 when 'client_id' then 2 when 'role_id' then 3 when 'user_id' then 4 end) desc
      
,

感谢 Gordon Linoff 的回答,我可以按照他的策略 (distinct on + order by + case) 找到一个很好的解决方案。这可能不是最优雅或最有效的,但它有效。如果可以进一步改进,请告诉我。

select distinct on (name) *
from policies
where level = $system_id  or
      level = $client_id or
      level = $role_id  or
      level = $user_id
order by name,(case when level = $system_id then 1 when level = $client_id then 2 when level = $role_id then 3 when level = $user_id then 4 end) desc;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...