簡體   English   中英

需要從Postgresql表中動態選擇JSON數組元素

[英]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

但是,我還需要一個級別-評估最后一項,如果它與名稱字段相同,則嘗試倒數第二個字段,依此類推。

任何幫助或指針將不勝感激!

Postgres 9.3中的json

在9.3版中很難做到這一點,因為缺少有用的功能。

方法1

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在注釋中提供的表達式,改進了從jsontext的轉換。 仍然有點破舊,但應該是安全的。

方法2

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 ,得到與上述相同的結果。

SQL提琴。

Postgres 9.4中的jsonjsonb

第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 其他都一樣。

手冊中的json / jsonb函數

相關答案以及更多說明:

暫無
暫無

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

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