अपडेट:PostgreSQL 9.4 में यह to_json . के परिचय के साथ बहुत सुधार करता है , json_build_object , json_object और json_build_array , हालांकि यह सभी क्षेत्रों को स्पष्ट रूप से नाम देने की आवश्यकता के कारण वर्बोज़ है:
select
json_build_object(
'id', u.id,
'name', u.name,
'email', u.email,
'user_role_id', u.user_role_id,
'user_role', json_build_object(
'id', ur.id,
'name', ur.name,
'description', ur.description,
'duty_id', ur.duty_id,
'duty', json_build_object(
'id', d.id,
'name', d.name
)
)
)
from users u
inner join user_roles ur on ur.id = u.user_role_id
inner join role_duties d on d.id = ur.duty_id;
पुराने संस्करणों के लिए, पढ़ें।
यह एक पंक्ति तक सीमित नहीं है, यह थोड़ा दर्दनाक है। आप AS . का उपयोग करके समग्र पंक्ति प्रकारों को उपनाम नहीं दे सकते , इसलिए आपको प्रभाव प्राप्त करने के लिए एक अलियास्ड सबक्वेरी एक्सप्रेशन या सीटीई का उपयोग करने की आवश्यकता है:
select row_to_json(row)
from (
select u.*, urd AS user_role
from users u
inner join (
select ur.*, d
from user_roles ur
inner join role_duties d on d.id = ur.duty_id
) urd(id,name,description,duty_id,duty) on urd.id = u.user_role_id
) row;
https://jsonprettyprint.com/ के माध्यम से उत्पादन करता है:
{
"id": 1,
"name": "Dan",
"email": "example@sqldat.com",
"user_role_id": 1,
"user_role": {
"id": 1,
"name": "admin",
"description": "Administrative duties in the system",
"duty_id": 1,
"duty": {
"id": 1,
"name": "Script Execution"
}
}
}
आप array_to_json(array_agg(...)) . का उपयोग करना चाहेंगे जब आपके पास 1:अनेक संबंध हों, btw।
उपरोक्त क्वेरी को आदर्श रूप से इस प्रकार लिखा जा सकता है:
select row_to_json(
ROW(u.*, ROW(ur.*, d AS duty) AS user_role)
)
from users u
inner join user_roles ur on ur.id = u.user_role_id
inner join role_duties d on d.id = ur.duty_id;
... लेकिन PostgreSQL का ROW कंस्ट्रक्टर AS को स्वीकार नहीं करता है स्तंभ उपनाम। दुख की बात है।
शुक्र है, वे उसी का अनुकूलन करते हैं। योजनाओं की तुलना करें:
- नेस्टेड सबक्वेरी संस्करण; बनाम
- बाद वाला नेस्टेड
ROWएलियास के साथ कंस्ट्रक्टर संस्करण हटा दिया गया ताकि यह निष्पादित हो
चूंकि सीटीई अनुकूलन बाड़ हैं, जंजीर वाले सीटीई का उपयोग करने के लिए नेस्टेड सबक्वेरी संस्करण को फिर से लिखना (WITH एक्सप्रेशन) भी अच्छा प्रदर्शन नहीं कर सकते हैं, और परिणामस्वरूप एक ही योजना नहीं होगी। इस मामले में जब तक हम row_to_json में कुछ सुधार नहीं कर लेते, तब तक आप बदसूरत नेस्टेड सबक्वेरी के साथ फंस गए हैं या ROW . में कॉलम नामों को ओवरराइड करने का तरीका कंस्ट्रक्टर अधिक सीधे।
वैसे भी, सामान्य तौर पर, सिद्धांत यह है कि जहां आप कॉलम के साथ एक json ऑब्जेक्ट बनाना चाहते हैं a, b, c , और आप चाहते हैं कि आप केवल अवैध सिंटैक्स लिख सकें:
ROW(a, b, c) AS outername(name1, name2, name3)
इसके बजाय आप पंक्ति-टाइप किए गए मान लौटाने वाली अदिश उपश्रेणियों का उपयोग कर सकते हैं:
(SELECT x FROM (SELECT a AS name1, b AS name2, c AS name3) x) AS outername
या:
(SELECT x FROM (SELECT a, b, c) AS x(name1, name2, name3)) AS outername
इसके अतिरिक्त, ध्यान रखें कि आप json लिख सकते हैं अतिरिक्त उद्धरण के बिना मान, उदा. यदि आप json_agg . का आउटपुट डालते हैं एक row_to_json . के भीतर , भीतरी json_agg परिणाम एक स्ट्रिंग के रूप में उद्धृत नहीं किया जाएगा, इसे सीधे json के रूप में शामिल किया जाएगा।
जैसे मनमाना उदाहरण में:
SELECT row_to_json(
(SELECT x FROM (SELECT
1 AS k1,
2 AS k2,
(SELECT json_agg( (SELECT x FROM (SELECT 1 AS a, 2 AS b) x) )
FROM generate_series(1,2) ) AS k3
) x),
true
);
आउटपुट है:
{"k1":1,
"k2":2,
"k3":[{"a":1,"b":2},
{"a":1,"b":2}]}
ध्यान दें कि json_agg उत्पाद, [{"a":1,"b":2}, {"a":1,"b":2}] , फिर से बच नहीं गया है, क्योंकि text होगा।
इसका मतलब है कि आप रचना कर सकते हैं पंक्तियों के निर्माण के लिए json संचालन, आपको हमेशा बेहद जटिल PostgreSQL समग्र प्रकार बनाने की आवश्यकता नहीं है, फिर row_to_json पर कॉल करें आउटपुट पर।