2017-10-07 117 views
1

我有這些表SQL查詢來JSON結果

destination (id integer, name text) 
activity (id integer, name text, destination_id integer) 
activity_duration (value numeric, unit text, label text, activity_id integer) 
activity_duration_price(amount numeric, currency_id integer, activity_duration_id integer) 

每個目的地有1個或多個活動,每個活動具有1周或更大的持續時間和持續時間的每個具有1個價。

這裏是我的查詢

select 
    d.id destination_id, 
    d.name destination_name, 
    count(a.id) as nb_activity, 
    string_agg('{"id":'||a.id||',"name":"'||a.name||'","pictures":"'||a.pictures||'","meta":{"price":'||amount||',"label":"'||label||'"}}',',') activities 
from destination d 
    left join activity a on (a.destination_id = d.id) 
    left join activity_duration ad on (activity_id = a.id) 
    left join activity_duration_price adp on (adp.activity_duration_id = ad.id) 
where d.id = any (array[142]) group by d.id, d.name order by nb_activity desc 

,這是爲string_agg

[{ 
    "id": 2, 
    "name": "visit tokyo", 
    "meta": { 
     "price": 210, 
     "label": "Adult" 
    } 
}, { 
    "id": 2, 
    "name": "visit tokyo", 
    "pictures": "{}", 
    "meta": { 
     "price": 170, 
     "label": "Children" 
    } 
}] 

結果正如你所看到的,元信息是有兩次相同的項目。

我想我對string_agg結果是這樣

[{ 
    "id": 2, 
    "name": "visit tokyo", 
    "meta": [{ 
      "price": 210, 
      "label": "Adult" 
     }, 
     { 
      "price": 170, 
      "label": "Children" 
     } 
    ] 
}] 

我怎樣才能得到這樣的結果?

+0

您在查詢中有類似'amount'和'label'的字段,您在表中沒有提到這個字段。 – Dmitry

+0

謝謝!我編輯了我的文章 – Rony

回答

1

array_agg - 創建行

的陣列

array_to_json - 創建JSON數組

再投JSON數組中的文本。

SELECT 
    d.id destination_id, 
    d.name destination_name, 
    count(a.id) AS nb_activity, 
    string_agg('{"id":'||a.id||',"name":"'||a.name||'","pictures":"'||a.pictures||'","meta":'|| 
      (
       SELECT array_to_json(array_agg(t))::TEXT --cast to TEXT to concatenate to the string 
       FROM 
       (
       SELECT 
        adp.amount, 
        ad.label 
       FROM activity a2 
        LEFT JOIN activity_duration ad ON (ad.activity_id = a2.id) 
        LEFT JOIN activity_duration_price adp ON (adp.activity_duration_id = ad.id) 
       ) AS t 
      ) 
      ||'}' 
    ,',' 
) AS activities 
FROM destination d 
    LEFT JOIN activity a ON (a.destination_id = d.id) 
WHERE d.id = ANY (ARRAY[142]) GROUP BY d.id, d.name ORDER BY nb_activity DESC 
+0

哇!那很完美!謝謝。 array_to_json功能非常棒! – Rony

+0

不客氣。 – Dmitry