PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

नेस्टेड जॉइन के साथ row_to_json() का उपयोग करना

अपडेट: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;

http://jsonprettyprint.com/ के माध्यम से उत्पादन करता है:

{
  "id": 1,
  "name": "Dan",
  "email": "[email protected]",
  "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 पर कॉल करें आउटपुट पर।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Django स्थिरता विफल रहता है, DatabaseError बताते हुए:प्रकार वर्ण भिन्न के लिए बहुत लंबा मान (50)

  2. क्लॉज द्वारा SELECT, WHERE और ORDER के लिए परिणाम का पुन:उपयोग कैसे करें?

  3. PostgreSQL में महीने का अंतिम दिन प्राप्त करें

  4. PostgreSQL 8.3 के बाद से OLTP प्रदर्शन

  5. मेरे पसंदीदा पोस्टग्रेएसक्यूएल प्रश्नों में से अधिक - और वे भी क्यों मायने रखते हैं