![](/img/trans.png)
[英]Select from JSON Array postgresql JSON column
[英]Need to select a JSON array element dynamically from a postgresql table
我的數據如下:
ID Name Data
1 Joe ["Mary","Joe"]
2 Mary ["Sarah","Mary","Mary"]
3 Bill ["Bill","Joe"]
4 James ["James","James","James"]
我想編寫一個查詢,該查詢從數組中選擇LAST元素,這不等於Name字段。 例如,我希望查詢返回以下結果:
ID Name Last
1 Joe Mary
2 Mary Sarah
3 Bill Joe
4 James (NULL)
我正在接近-我可以使用以下查詢選擇最后一個元素:
SELECT ID, Name,
(Data::json->(json_array_length(Data::json)-1))::text AS Last
FROM table;
ID Name Last
1 Joe Joe
2 Mary Mary
3 Bill Joe
4 James James
但是,我還需要一個級別-評估最后一項,如果它與名稱字段相同,則嘗試倒數第二個字段,依此類推。
任何幫助或指針將不勝感激!
json
在9.3版中很難做到這一點,因為缺少有用的功能。
在LEFT JOIN LATERAL
(干凈且符合標准)中嵌套,將json
雙引號修剪為強制轉換為text
。 請參閱下面的鏈接。
SELECT DISTINCT ON (1)
t.id, t.name, d.last
FROM tbl t
LEFT JOIN LATERAL (
SELECT ('[' || d::text || ']')::json->>0 AS last
FROM json_array_elements(t.data) d
) d ON d.last <> t.name
ORDER BY 1, row_number() OVER () DESC;
盡管這可行,但我從未見過失敗,但未嵌套元素的順序取決於未記錄的行為。 請參閱下面的鏈接!
使用@pozs在注釋中提供的表達式,改進了從json
到text
的轉換。 仍然有點破舊,但應該是安全的。
SELECT DISTINCT ON (1)
id, name, NULLIF(last, name) AS last
FROM (
SELECT t.id, t.name
,('[' || json_array_elements(t.data)::text || ']')::json->>0 AS last
, row_number() OVER () AS rn
FROM tbl t
) sub
ORDER BY 1, (last = name), rn DESC;
SELECT
列表中(非標准)。 rn
)(更可靠)。 text
。 ORDER BY
子句中的表達式(last = name)
對匹配的名稱進行最后排序(但在NULL之前)。 因此,僅當沒有其他名稱可用時,才選擇匹配的名稱。 下面的最后一個鏈接。 在SELECT
列表中, NULLIF
將匹配的名稱替換為NULL
,得到與上述相同的結果。 json
或jsonb
第9.4頁提供了所有必要的改進:
SELECT DISTINCT ON (1)
t.id, t.name, d.last
FROM tbl t
LEFT JOIN LATERAL json_array_elements_text(data) WITH ORDINALITY d(last, rn)
ON d.last <> t.name
ORDER BY d.rn DESC;
將jsonb_array_elements_text()
用於jsonb
。 其他都一樣。
相關答案以及更多說明:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.