2017-11-11 90 views
0

SQL新手在這裏。POSTGRES:如何做循環和如何加入循環內?

我有兩個表像這些

表:訂單

enter image description here

CREATE TABLE orders (
ID serial NOT NULL PRIMARY KEY, 
data json NOT NULL 
); 

INSERT INTO orders (data) 
VALUES 
(
'{"customer":"John Doe","items":[{"1234":{"attributes":{"name":"parent"}},"id":"1234","isPhone":true,"items":[{"5678":{"attributes":{"name":"child"}},"id":"5678","isPhone":false}]},{"9012":{"attributes":{"name":"parent"}},"id":"9012","isPhone":true,"items":[{"3456":{"attributes":{"name":"child"}},"id":"3456","isPhone":false}]}]}' 
); 

INSERT INTO orders (data) 
VALUES 
(
'{"customer":"John Doe","items":[{"7890":{"attributes":{"name":"parent"}},"id":"7890","isPhone":true,"items":[{"0987":{"attributes":{"name":"child"}},"id":"0987","isPhone":false}]},{"6543":{"attributes":{"name":"parent"}},"id":"6543","isPhone":true,"items":[{"2109":{"attributes":{"name":"child"}},"id":"2109","isPhone":false}]}]}' 
); 

表:積壓

enter image description here

CREATE TABLE backlog (
ID serial NOT NULL PRIMARY KEY, 
data json NOT NULL 
); 

    INSERT INTO backlog (data) 
VALUES 
('{"id":"5678","isAvailable":true,"order_id":1}'), 
('{"id":"9012","isAvailable":true,"order_id":1}'), 
('{"id":"3456","isAvailable":false,"order_id":1}'), 
('{"id":"7890","isAvailable":false,"order_id":2}'), 
('{"id":"0987","isAvailable":false,"order_id":2}'), 
('{"id":"6543","isAvailable":false,"order_id":2}'), 
('{"id":"2109","isAvailable":false,"order_id":2}'), 
('{"id":"1234","isAvailable":true,"order_id":1}') 

現在我需要每個order.data.items陣列裏面循環遞歸以獲得兩家母公司&子項的id和做基礎上,Backlog.data.id聯接積壓表

最終輸出喜歡被

enter image description here

如果我沒有正確地解釋我的需求,請評論我會努力讓儘可能多詳細。

在此先感謝。

+2

如果這是一個SQL數據庫,我會建議你改變你的數據結構。這看起來更像NoSQL數據庫。 –

+0

postgres有jsonb支持,所以去了SQL有nosql支持。 – Sathish

+1

僅僅因爲Postgres具有相當不錯的JSON/NoSQL支持,並不意味着規則或適當的數據庫設計應該被拋棄。不要對所有東西都使用JSON。使用正確的標準化模型,這與加入兩個表格一樣簡單。見例如這裏:https://blog.2ndquadrant.com/postgresql-anti-patterns-unnecessary-jsonhstore-dynamic-columns/ –

回答

0

你可以用子查詢(或CTE)和generate_series()來做到這一點。

select baz from (select o.data->'items'->generate_series(0, json_array_length(o.data->'items') - 1)->>'id' as foo, b.data->>'id' as bar, b.data as baz from orders as o, backlog as b) as t where foo = bar; 

這將返回

      baz       
----------------------------------------------------- 
{"id": "9012", "order_id": 1, "isAvailable": true} 
{"id": "7890", "order_id": 2, "isAvailable": false} 
{"id": "6543", "order_id": 2, "isAvailable": false} 
{"id": "1234", "order_id": 1, "isAvailable": true} 
(4 rows) 

解構和理解我的查詢被留作練習。

和閱讀文檔: https://www.postgresql.org/docs/current/static/functions-json.html

+0

我很可能沒有得到您父母和孩子的所有要求,但我希望這能讓您走上正確的道路。 –