簡體   English   中英

postgresql unnest 和 pivot int 數組列

[英]postgresql unnest and pivot int array column

我有下表

create table test(id serial, key int,type text,words text[],numbers int[] );

insert into test(key,type,words) select 1,'Name',array['Table'];
insert into test(key,type,numbers) select 1,'product_id',array[2];
insert into test(key,type,numbers) select 1,'price',array[40];
insert into test(key,type,numbers) select 1,'Region',array[23,59];
insert into test(key,type,words) select 2,'Name',array['Table1'];
insert into test(key,type,numbers) select 2,'product_id',array[1];
insert into test(key,type,numbers) select 2,'price',array[34];
insert into test(key,type,numbers) select 2,'Region',array[23,59,61];
insert into test(key,type,words) select 3,'Name',array['Chair'];
insert into test(key,type,numbers) select 3,'product_id',array[5];

我正在為用戶使用以下查詢 pivot 表。

select key,
max(array_to_string(words,',')) filter(where type='Name') as "Name",
cast(max(array_to_string(numbers,',')) filter(where type='product_id') as int) as "product_id", 
cast(max(array_to_string(numbers,',')) filter(where type='price') as int) as "price" ,
max(array_to_string(numbers,',')) filter(where type='Region') as "Region"
from test group by key

在此處輸入圖像描述

但是我無法在 Pivot 期間取消嵌套 Region 列,以便使用 Region 列與另一個表連接。

我預期的 output 低於

在此處輸入圖像描述

由於我們使用 unnest("Region") 來處理 pivot。 每個產品必須有一行包含區域數據。 或者下面的代碼將通過創建一個 null 數組來解決問題。

unnest(CASE WHEN array_length("Region", 1) >= 1
                    THEN "Region"
                    ELSE '{null}'::int[] END) 

架構:

 create table test(id serial, key int,type text,words text[],numbers int[] ); insert into test(key,type,words) select 1,'Name',array['Table']; insert into test(key,type,numbers) select 1,'product_id',array[2]; insert into test(key,type,numbers) select 1,'price',array[40]; insert into test(key,type,numbers) select 1,'Region',array[23,59]; insert into test(key,type,words) select 2,'Name',array['Table1']; insert into test(key,type,numbers) select 2,'product_id',array[1]; insert into test(key,type,numbers) select 2,'price',array[34]; insert into test(key,type,numbers) select 2,'Region',array[23,59,61]; insert into test(key,type,words) select 3,'Name',array['Chair']; insert into test(key,type,numbers) select 3,'product_id',array[5];
 select key,"Name",product_id,price,unnest(CASE WHEN array_length("Region", 1) >= 1 THEN "Region" ELSE '{null}'::int[] END) from ( select key, max(array_to_string(words,',')) filter(where type='Name') as "Name", cast(max(array_to_string(numbers,',')) filter(where type='product_id') as int) as "product_id", cast(max(array_to_string(numbers,',')) filter(where type='price') as int) as "price", max(numbers) filter(where type='Region') as "Region" from test group by key )t order by key
鑰匙 姓名 product_id 價格 不嵌套
1 桌子 2 40 23
1 桌子 2 40 59
2 表格1 1 34 23
2 表格1 1 34 59
2 表格1 1 34 61
3 椅子 5 null null

db<> 在這里擺弄

非常奇怪的數據庫設計......我假設你繼承了它?

如果沒有其他數組值的基數 > 1,那么您可以簡單地unnest

select
  key,
  (max (words) filter (where type = 'Name'))[1] as name,
  (max (numbers) filter (where type = 'product_id'))[1] as product_id,
  (max (numbers) filter (where type = 'price'))[1] as price,
  unnest (max (numbers) filter (where type = 'Region')) as region
from test
group by key

如果它們可以有多個值,那也可以處理。

-- 編輯 2021 年 3 月 15 日 --

簡短版本:針對 null 的unnest不會產生一行,因此如果將 null 值合並到單個 null 元素的數組中,則應注意以下部分:

select
  key,
  (max (words) filter (where type = 'Name'))[1] as name,
  (max (numbers) filter (where type = 'product_id'))[1] as product_id,
  (max (numbers) filter (where type = 'price'))[1] as price,
  unnest (coalesce (max (numbers) filter (where type = 'Region'), array[null]::integer[])) as region
from test
group by key
order by key

現在對於你沒有問的部分......我和至少另一個人一直在輕輕地提醒你,你的數據庫設計將在每一個轉折點都會導致多個問題。 它在生產中的事實並不意味着您不應該盡快修復它。

這種設計就是所謂的 EAV - 實體 - 屬性 - 值。 它有它的用例,但像大多數好東西一樣,它也可以在不應該應用的時候應用。 想到的用例是,如果您希望用戶能夠為某些對象動態添加屬性。 即使那樣,也可能有更好/更簡單的方法。

舉個例子,如果你有 100 萬個對象,5 個屬性意味着你必須將其存儲為 500 萬行,並且大部分空間將用於重復鍵和屬性名稱。

只是思考的食物。 我們可以繼續對您發現的每個新場景進行分類,但最好重做設計。

暫無
暫無

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

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