2014-05-08 64 views
1

長話短說,我該如何使用1像所示例子中n選擇數據構建JSON:pgsql的1到n關係到JSON

SELECT table1.id AS id1,table2.id AS id2,t_id,label 
FROM table1 LEFT JOIN table2 ON table2.t_id = table1.id 

result 
|id1|id2|t_id|label| 
+---+---+----+-----+ 
|1 | 1 | 1 | a | 
| | 2 | 1 | b | 
| | 3 | 1 | c | 
| | 4 | 1 | d | 
|2 | 5 | 2 | x | 
| | 6 | 2 | y | 

轉成這個

SELECT table1.id, build_json(table2.id,table2.label) AS json_data 
FROM table1 JOIN table2 ON table2.t_id = table1.id 
GROUP BY table1.id 

|id1|json_data 
+--+----------------- 
|1 |{"1":"a","2":"b","3":"c","4":"d"} 
|2 |{"5":"x","6":"y"} 

我的猜測最開始woulb來構建從列的陣列

Hstore而不是JSON將是確定太

回答

0

以及你的表結構是有點奇怪(是看起來更像報告比表),所以我在這裏看到兩個任務:

與正確id1更換空。你可以像下面這樣做

with cte1 as (
    select 
     sum(case when id1 is null then 0 else 1 end) over (order by t_id) as id1_partition, 
     id1, id2, label 
    from Table1 
), cte2 as (
    select 
     first_value(id1) over(partition by id1_partition) as id1, 
     id2, label 
    from cte1 
) 
select * 
from cte2 

現在你必須彙總數據json。至於我記得,有沒有這樣的PostgreSQL的功能,所以你必須手動連接的數據:

with cte1 as (
    select 
     sum(case when id1 is null then 0 else 1 end) over (order by t_id) as id1_partition, 
     id1, id2, label 
    from Table1 
), cte2 as (
    select 
     first_value(id1) over(partition by id1_partition) as id1, 
     id2, label 
    from cte1 
) 
select 
    id1, 
    ('{' || string_agg('"' || id2 || '":' || to_json(label), ',') || '}')::json as json_data 
from cte2 
group by id1 

sql fiddle demo

如果你想轉換成hstore

with cte1 as (
    select 
     sum(case when id1 is null then 0 else 1 end) over (order by t_id) as id1_partition, 
     id1, id2, label 
    from Table1 
), cte2 as (
    select 
     first_value(id1) over(partition by id1_partition) as id1, 
     id2, label 
    from cte1 
) 
select 
    c.id1, hstore(array_agg(c.id2)::text[], array_agg(c.label)::text[]) 
from cte2 as c 
group by c.id1 

sql fiddle demo