SQL 需要查询帮助:如何在同一个 table 中排除或优先处理 SQL 中的行
SQL query help needed: How to exclude or prioritize rows in SQL in the same table
我有问题
我有一个包含用户、角色、客户端和系统的应用程序。
我有一个名为 'policies' 的 table,其中包含我的应用程序所依赖的 22 policies/rules。
22 个中的每一个都可以在一个或多个级别上定义。
级别可以是:系统、客户端、角色或用户。
一个系统有 N 个客户端,一个客户端有 N 个角色,一个角色有 N 个用户。
默认情况下,所有 22 个策略都是在系统级别定义的,但它们可以在任何较低级别被覆盖。
请参阅下面的 table 示例。为系统定义了 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;
我有问题
我有一个包含用户、角色、客户端和系统的应用程序。 我有一个名为 'policies' 的 table,其中包含我的应用程序所依赖的 22 policies/rules。 22 个中的每一个都可以在一个或多个级别上定义。 级别可以是:系统、客户端、角色或用户。 一个系统有 N 个客户端,一个客户端有 N 个角色,一个角色有 N 个用户。 默认情况下,所有 22 个策略都是在系统级别定义的,但它们可以在任何较低级别被覆盖。
请参阅下面的 table 示例。为系统定义了 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;