[英]Postgres select and merge rows
我正在一張看起來像這樣的桌子上工作:
user_id | key | scope | value
--------+-------------+-----------+-------
1 | someSetting | user | false
1 | someSetting | group | true
1 | someSetting | company | false
2 | someSetting | user | false
2 | someSetting | group | true
3 | someSetting | user | false
4 | someSetting | group | true
設置位於一個層次結構中: company -> group -> user
,其中用戶覆蓋了組,而該組又覆蓋了公司。 當通過user_id
查詢時,我想通過此層次結構有效地合並設置(如果存在)。 對於上面的示例,我希望將其作為結果:
user_id | key | value
--------+-------------+-------
1 | someSetting | false
2 | someSetting | true
3 | someSetting | false
4 | someSetting | true
我目前正在從Postgres檢索行之后進行合並操作,但是如果可以在查詢本身中完成,它將更加高效。 我查看了聚合函數,但看起來其中任何一個都不符合我的要求。
這似乎很簡單,我相信可以使用Postgres來完成。 任何指針表示贊賞!
您可以將ROW_NUMBER()
窗口函數與PARTITION BY
和非常酷的ORDER BY
。
理念:
user_id
和ORDER BY
自定義排序順序的每條記錄獲取ROW_NUMBER
。 a
WHERE
行號為1中SELECT
您想要的所有內容。 例:
WITH a AS
(
SELECT user_id
, key
, scope
, ROW_NUMBER() OVER(PARTITION BY user_id
ORDER BY array_position(array['user','group','company'], scope)) AS rno
FROM test
)
SELECT user_id
, key
, scope
FROM a
WHERE rno = 1;
DBFiddle演示它的工作原理。
獎勵:如果您要創建一個函數來執行此操作,您甚至可以傳入其他數組來設置自定義排序順序。
您要做的是將范圍設置從單獨的行更改為單獨的列,因此您的記錄集如下所示(請注意,我使用0表示false,使用1表示true):
+---------+-------------+--------------+---------------+-----------------+ | user_id | key | user_setting | group_setting | company_setting | +---------+-------------+--------------+---------------+-----------------+ | 1 | someSetting | 0 | 1 | 0 | | 2 | someSetting | 0 | 1 | NULL | | 3 | someSetting | 0 | NULL | NULL | | 4 | someSetting | NULL | 1 | NULL | +---------+-------------+--------------+---------------+-----------------+
為此,您有幾種選擇。 這是其中之一,使用條件聚合。 基本上,您是按user_id
和key
分組的,然后將聚合函數(可以是MIN
或MAX
)與CASE
語句結合使用:
WITH settings_pivot AS ( SELECT [user_id], [key], MIN(CASE WHEN [scope] = 'user' THEN [value] ELSE NULL END) AS user_setting, MIN(CASE WHEN [scope] = 'group' THEN [value] ELSE NULL END) AS group_setting, MIN(CASE WHEN [scope] = 'company' THEN [value] ELSE NULL END) AS company_setting FROM settings GROUP BY [user_id], [key] ) SELECT [user_id], [key], COALESCE(user_setting, group_setting, company_setting) AS derived_setting FROM settings_pivot
如果您只是從settings_pivot CTE中SELECT *
,那么您將獲得開始時獲得的數據透視表。 但是,使用COALESCE
可以按照您指定的優先級進行操作。
注意 :由於我的計算機上的Postgres不想啟動,因此我正在使用SQL Server。 因此,您必須將方括號替換為雙引號: "user_id"
而不是[user_id]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.