![](/img/trans.png)
[英]How to extract values from array json column into multiple rows in Postgresql?
[英]Select rows where nested json array field includes any of values from a provided array in PostgreSQL?
我正在嘗試編寫一個 sql 查詢,該查詢將在表中找到與提供的 json 數組的任何值匹配的行。
更具體地說,我有以下數據庫表:
CREATE TABLE mytable (
name text,
id SERIAL PRIMARY KEY,
config json,
matching boolean
);
INSERT INTO "mytable"(
"name", "id", "config", "matching"
)
VALUES
(
E 'Name 1', 50,
E '{"employees":[1,7],"industries":["1","3","4","13","14","16"],"levels":["1110","1111","1112","1113","1114"],"revenue":[0,5],"states":["AK","Al","AR","AZ","CA","CO","CT","DC","DE","FL","GA","HI","IA","ID","IL"]}',
TRUE
),
(
E 'Name 2', 63,
E '{"employees":[3,5],"industries":["1"],"levels":["1110"],"revenue":[2,5],"states":["AK","AZ","CA","CO","HI","ID","MT","NM","NV","OR","UT","WA","WY"]}',
TRUE,
),
(
E 'Name 3', 56,
E '{"employees":[0,0],"industries":["14"],"levels":["1111"],"revenue":[7,7],"states":["AK","AZ","CA","CO","HI","ID","MT","NM","NV","OR","UT","WA","WY"]}',
TRUE,
),
(
E 'Name 4', 61,
E '{"employees":[3,8],"industries":["1"],"levels":["1110"],"revenue":[0,5],"states":["AK","AZ","CA","CO","HI","ID","WA","WY"]}',
FALSE
);
我需要使用給定的過濾參數對此表執行搜索查詢。 過濾參數基本對應config
字段中的 json 鍵。 它們來自客戶端,看起來像這樣:
{"employees": [1, 8], "industries": ["12", "5"]}
{"states": ["LA", "WA", "CA"], "levels": ["1100", "1100"], "employees": [3]}
並且給定這樣的過濾器,我需要在我的表中找到包含來自提供的每個過濾器鍵的相應過濾器鍵的任何數組元素的行。
所以給定過濾器{"employees": [1, 8], "industries": ["12", "5"]}
查詢必須返回所有行,其中( config
字段中的employees
鍵包含1
或8
並且config
字段中的industries
鍵包含12
或5
);
我需要從 javascript 代碼動態生成這樣的查詢,以便我可以通過添加/刪除AND
運算符的某個參數包含/排除過濾。
到目前為止,我所擁有的是一個超級長時間運行的查詢,它在config
字段中生成所有可能的數組元素組合,感覺非常錯誤:
select * from mytable
cross join lateral json_array_elements(config->'employees') as e1
cross join lateral json_array_elements(config->'states') as e2
cross join lateral json_array_elements(config->'levels') as e3
cross join lateral json_array_elements(config->'revenue') as e4;
我也嘗試過這樣做:
select * from mytable
where
matching = TRUE
and (config->'employees')::jsonb @> ANY(ARRAY ['[1, 7, 8]']::jsonb[])
and (config->'states')::jsonb @> ANY(ARRAY ['["AK", "AZ"]']::jsonb[])
and ........;
然而這並沒有奏效,雖然看起來很有希望。
另外,我試過玩?|
運營商,但無濟於事。
基本上,我需要的是:給定 json 字段中的數組鍵檢查該字段是否包含另一個數組中提供的任何值(這是我的過濾參數); 我必須動態地為多個過濾參數執行此操作。
所以邏輯如下:
select all rows from the table
*where*
matching = TRUE
*and* config->key1 includes any of the keys from [5,6,8,7]
*and* config->key2 includes any of the keys from [8,6,2]
*and* so forth;
你能幫我實現這樣一個 sql 查詢嗎?
或者也許這樣的 sql 查詢總是非常慢,最好在數據庫級別之外進行這種過濾?
我會嘗試類似的東西。 我想有一定的副作用(例如,如果比較數據為空怎么辦?)而且我沒有在更大的數據集上測試它......這只是我想到的第一個......:
SELECT
*
FROM
mytable t
JOIN (SELECT '{"states": ["LA", "WA", "CA"], "levels": ["1100", "1100"], "employees": [3]}'::json as data) c
ON
CASE WHEN c.data -> 'employees' IS NOT NULL THEN
ARRAY(SELECT json_array_elements_text(t.config -> 'employees')) && ARRAY(SELECT json_array_elements_text(c.data -> 'employees'))
ELSE TRUE END
AND
CASE WHEN c.data -> 'industries' IS NOT NULL THEN
ARRAY(SELECT json_array_elements_text(t.config -> 'industries')) && ARRAY(SELECT json_array_elements_text(c.data -> 'industries'))
ELSE TRUE END
AND
CASE WHEN c.data -> 'states' IS NOT NULL THEN
ARRAY(SELECT json_array_elements_text(t.config -> 'states')) && ARRAY(SELECT json_array_elements_text(c.data -> 'states'))
ELSE TRUE END
AND
CASE WHEN c.data -> 'revenue' IS NOT NULL THEN
ARRAY(SELECT json_array_elements_text(t.config -> 'revenue')) && ARRAY(SELECT json_array_elements_text(c.data -> 'revenue'))
ELSE TRUE END
AND
CASE WHEN c.data -> 'levels' IS NOT NULL THEN
ARRAY(SELECT json_array_elements_text(t.config -> 'levels')) && ARRAY(SELECT json_array_elements_text(c.data -> 'levels'))
ELSE TRUE END
連接條件說明:
CASE WHEN c.data -> 'levels' IS NOT NULL THEN
ARRAY(SELECT json_array_elements_text(t.config -> 'levels')) && ARRAY(SELECT json_array_elements_text(c.data -> 'levels'))
ELSE TRUE END
如果您的比較數據不包含特定屬性,則條件為true
,因此將被忽略。 If it contains an attribute, compare the table and comparision arrays for this attribute by transforming both JSON arrays into simple Postgres arrays
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.