我們有一個帶有 jsonb 列的 PostgreSQL 表。json 中的一些節點可以作為陣列或物件進入輸入。我正在嘗試撰寫一個查詢,如果節點是一個陣列并且陣列大小大于 1,它將給我陣列長度
select
count(*) as policycount, policynumber
from
policymaster
where
jsonb_typeof((payload-> 'node1'::text) -> 'node2'::text) = 'array'
-- and jsonb_array_length((payload-> 'node1'::text) -> 'node2'::text) > 1
group by policynumber
order by 1 desc
如果我嘗試添加
and jsonb_array_length((payload-> 'node1' -> 'node2') > 1
然后我得到
SQL Error [42601]: ERROR: syntax error at or near "group"
Position: 310
如果我嘗試
and jsonb_array_length((payload-> 'node1'::text) -> 'node2'::text) > 1
我明白了
SQL Error [22023]: ERROR: cannot get array length of a non-array
由于它是物件和陣列的混合體,因此需要檢查陣列
where
jsonb_typeof((payload-> 'node1'::text) -> 'node2'::text) = 'array'
似乎也沒有幫助
如何僅獲取 node2 是陣列且該陣列的大小大于 1 的那些記錄?
子問題
當我按原樣執行@jjanes 查詢時
select
count(*) as policycount, policynumber
from
policymaster
where
case when jsonb_typeof((payload-> 'node1'::text) -> 'node2'::text) = 'array'
then jsonb_array_length((payload-> 'node1'::text) -> 'node2'::text) > 1
else false end
group by policynumber
order by 1 desc ;
結果是空的。
當我將輸入引數更改為下面的兩個函式呼叫時,它給出了我期望的結果
select
count(*) as policycount, policynumber
from
policymaster
where
case when jsonb_typeof(payload-> 'node1' -> 'node2') = 'array'
then jsonb_array_length(payload-> 'node1' -> 'node2') > 1
else false end
group by policynumber
order by 1 desc ;
我剛開始研究 PostgreSQL,所以對 json / jsonb 函式沒有完全了解。
據我了解::text,任何 jsonb 物件上的部分都將其從 jsonb 轉換為文本,但不確定這部分的具體行為方式
(payload-> 'node1'::text) -> 'node2'::text)
你能解釋一下那部分嗎?也許然后它會幫助我理解為什么::text對這兩個節點的查詢在 case 陳述句中不起作用,但在以不同方式單獨使用時起作用
謝謝
uj5u.com熱心網友回復:
語法錯誤只是因為您的括號不平衡。如果你解決了這個問題,那么你會得到你一直得到的另??一個錯誤。
不能保證僅使用 AND 會以您想要的方式短路。您可以使用 CASE 強制第二個不執行,除非第一個給出所需的結果,如檔案中所述:
select
count(*) as policycount, policynumber
from
policymaster
where
case when jsonb_typeof((payload-> 'node1'::text) -> 'node2'::text) = 'array'
then jsonb_array_length((payload-> 'node1'::text) -> 'node2'::text) > 1
else false end
group by policynumber
order by 1 desc ;
CTE 在最近的版本中不起作用的原因是規劃器只是將 CTE 折疊到查詢的其余部分中,因此提出了相同的計劃。你可以用with temp_cte as MATERIALIZED (
uj5u.com熱心網友回復:
可能這會有所幫助
with temp_cte as (
select * from policymaster
where jsonb_typeof(payload-> 'node1' -> 'node2')='array'
)
select
policynumber, count(*) as policycount
from
temp_cte
where
jsonb_array_length(payload-> 'node1' -> 'node2') > 1
group by policynumber
order by 1 desc
您不應該將陣列轉換為 jsonb_array_length 函式中的文本。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/524746.html
上一篇:如何在JS中將兩個陣列與物件進行比較期間找到相似項的索引
下一篇:嘗試遍歷陣列并注釋它們
