簡體   English   中英

SQL 需要查詢幫助:如何在同一個表中排除或優先考慮 SQL 中的行

[英]SQL query help needed: How to exclude or prioritize rows in SQL in the same table

我遇到的問題

我有一個包含用戶、角色、客戶端和系統的應用程序。 我有一個名為“policies”的表,其中包含我的應用程序依賴的 22 條策略/規則。 22 個中的每一個都可以定義為一個或多個級別。 級別可以是:系統、客戶端、角色或用戶。 一個系統有 N 個客戶端,一個客戶端有 N 個角色,一個角色有 N 個用戶。 默認情況下,所有 22 個策略都在系統級別定義,但它們可以在任何較低級別被覆蓋。

請參閱下表作為示例。 為系統定義了 22 個策略 (system_id)。 請注意如何在客戶端、角色和用戶級別(使用相應的 id)設置 policy_1。


            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

QUERY OUTPUT在最低級別設置的 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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM