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

Postgres क्वेरी में तालिका के लिए FROM-खंड प्रविष्टि का अमान्य संदर्भ

त्रुटि के लिए स्पष्टीकरण

त्रुटि संदेश का तात्कालिक कारण यह है कि कोई भी स्पष्ट JOIN अल्पविराम से अधिक मजबूत बांधता है (, ) जो अन्यथा CROSS JOIN . के बराबर है , लेकिन (प्रति दस्तावेज़ ):

बोल्ड जोर मेरा।
यही आपकी त्रुटि का कारण है। आप कर सकते थे इसे ठीक करें:

FROM  appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...

लेकिन यही एकमात्र समस्या नहीं थी। पढ़ते रहिये।

कोई यह तर्क दे सकता है कि पोस्टग्रेज़ को यह देखना चाहिए कि LATERAL केवल बाईं ओर की तालिका के संबंध में समझ में आता है। लेकिन ऐसा नहीं है।

धारणा

मैंने टेबल उपनाम जोड़े, और टेबल-योग्य सभी कॉलम नामों को संदिग्ध के रूप में जोड़ा। इस पर रहते हुए, मैंने JSON संदर्भों को सरल बनाया और कुछ शोर को कम किया। यह क्वेरी अभी भी गलत है :

SELECT i.data ->> 'id'          AS id,
       i.data ->> 'name'        AS name,
       i.data ->> 'curator'     AS curator,
       i.data ->  '$isValid'    AS "$isValid",
       i.data ->  'customer'    AS customer,
       i.data ->  '$createdTS'  AS "$createdTS",
       i.data ->  '$updatedTS'  AS "$updatedTS",
       i.data ->  '$isComplete' AS "$isComplete",
       count(k.keys)::numeric   AS "numProducts",
       u.created_at
FROM   appointment_intakes i
     , jsonb_object_keys(i.data -> 'products') AS k(keys)
JOIN   appointment_intake_users u ON u.appointment_intake_id = i.id
#{where_clause}
GROUP  BY i.id

कच्ची क्वेरी

उपरोक्त और कुछ और मान्यताओं के आधार पर, समाधान एक सबक्वेरी में गिनती करना हो सकता है:

SELECT i.data ->> 'id'          AS id,
       i.data ->> 'name'        AS name,
       i.data ->> 'curator'     AS curator,
       i.data ->  '$isValid'    AS "$isValid",
       i.data ->  'customer'    AS customer,
       i.data ->  '$createdTS'  AS "$createdTS",
       i.data ->  '$updatedTS'  AS "$updatedTS",
       i.data ->  '$isComplete' AS "$isComplete",
       (SELECT count(*)::numeric
        FROM   jsonb_object_keys(i.data -> 'products')) AS "numProducts",
       min(u.created_at)        AS created_at
FROM   appointment_intakes i
JOIN   appointment_intake_users u ON u.appointment_intake_id = i.id
--     #{where_clause}
GROUP  BY i.id;

चूँकि आपको केवल गिनती की आवश्यकता है, इसलिए मैंने आपका LATERAL रूपांतरित कर दिया है एक सहसंबद्ध सबक्वेरी में शामिल हों, जिससे कई 1:n संयुक्त से उत्पन्न होने वाली विभिन्न समस्याओं से बचा जा सके। अधिक:

आपको जरूरत पहचानकर्ताओं से ठीक से बचने के लिए, तैयार कथन . का उपयोग करें और मानों पास करें मूल्यों के रूप में। क्वेरी स्ट्रिंग में मानों को संयोजित न करें। यह यादृच्छिक त्रुटियों या SQL इंजेक्शन के लिए आमंत्रण है हमले। PHP के लिए हालिया उदाहरण:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL में अधिकतम (order_field) + 1 लेन-देन के साथ पंक्तियों को कैसे सम्मिलित करें

  2. ट्रिगर त्रुटि पर रोलबैक लेनदेन

  3. GitHub क्रियाएँ:GitHub क्रियाओं में Postgres से कैसे जुड़ें?

  4. PostgreSQL - एक घंटे से अधिक पुराने डेटा को हटाना, और फिर उसी तालिका में नया डेटा सम्मिलित करना

  5. पोस्टग्रेज पर टेबल से डेटा इंटरसेक्ट कैसे करें