[英]SQL query map values in multiple columns to different value in another table
我有一個包含 1000 多列的主表,其中許多列包含唯一代碼。 這些代碼映射到另一個表中的值。 我正在嘗試使用映射值生成主表的副本。
主表
id name cty city segment
== ==== === === ===
01 John 001 012 081
02 Sam 001 019 110
03 Lee 005 029 110
映射表
id code value
== ==== ===
01 001 USA
02 012 San Francisco
03 019 New York City
04 005 Canada
05 029 Vancouver
06 081 Retail
07 110 Corporate
我想要的輸出:
id name cty city segment
== ==== === === ===
01 John USA San Francisco Retail
02 Sam USA New York City Corporate
03 Lee Canada Vancouver Corporate
當然,我可以運行許多連接,如下所示:
SELECT m.id, m.name, z1.value, z2.value, z3.value
FROM Master m
INNER JOIN mapping z1 ON m.cty = z1.code
INNER JOIN mapping z2 ON m.city = z2.code
INNER JOIN mapping z3 ON m.segment = z3.code
但是,有 100 列映射到代碼。 是否有一個 SQL 查詢可以達到相同的結果或者比編寫多個INNER JOINS
執行起來更便宜?
理想的結果是我可以運行一個簡單的SELECT * FROM Master...
在這里我不必拼出每一列,同時將所有代碼映射到它們各自的值,同時我看不到代碼。
我相信如果您的結果集依賴於它,您將無法逃避這數百個連接,但是您可以通過將它們保存到VIEW
來將它們隱藏起來:
創建視圖
CREATE VIEW my_view AS
SELECT m.id, m.name, z1.value as city1, z2.value as city2, z3.value as segment
FROM Master m
INNER JOIN mapping z1 ON m.cty = z1.code
INNER JOIN mapping z2 ON m.city = z2.code
INNER JOIN mapping z3 ON m.segment = z3.code;
查詢視圖
SELECT * FROM my_view;
視圖只是執行先前保存的查詢並顯示其結果。 但如果您的查詢太耗時,您可以創建一個所謂的MATERIALIZED VIEW
。 顧名思義,它是物理創建在磁盤上的,不需要每次都執行其原始查詢。
要create
MATERIALIZED VIEW
只需將MATERIALIZED
添加到語句中
CREATE MATERIALIZED VIEW my_view AS
SELECT ...
並refresh
其值只是做
REFRESH MATERIALIZED VIEW my_view;
顯然所有值都是字符串(文本、varchar),您可以構建映射的 JSON 鍵/值對,然后動態訪問鍵。
我認為這不會更快(甚至可能更慢),但它只需要一個連接並且名稱是動態的。
select m.id, m.name,
mp.mappings ->> 'cty' as cty,
mp.mappings ->> 'city' as city,
mp.mappings ->> 'segment' as segment,
mp.mappings as all_mappings
from master m
left join lateral (
select jsonb_object_agg(k, value) as mappings
from mapping ma
join jsonb_each_text(to_jsonb(m) - 'id' - 'name') as t(k,val)
on ma.code = t.val
) mp on true
jsonb_each_text(to_jsonb(m) - 'id' - 'name')
創建一個 JSON 值,其中主表中的列名是鍵。 鍵(=列名稱) id
和name
將從該 JSON 中刪除。
然后使用那里的值連接映射表。 結果是聚合成單個 JSON 值,其中主表中的列名是鍵,映射表中的值是值。
沒有真正的方法可以單獨指定每個輸出列。 如果您不是真的不需要各個列,您可以選擇mp.mappings
並將所有值作為單個 JSON 獲取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.