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

Generate_series के साथ पिछले 18 महीनों के लिए योग और रनिंग बैलेंस का चयन

मूल समाधान

महीनों की पूरी सूची तैयार करें और LEFT JOIN इसके लिए बाकी:

SELECT *
FROM  (
   SELECT to_char(m, 'YYYY-MON') AS yyyymmm
   FROM   generate_series(<start_date>, <end_date>, interval '1 month') m
   ) m
LEFT  JOIN ( <your query here> ) q USING (yyyymmm);

अधिक स्पष्टीकरण के साथ संबंधित उत्तर:

आपके मामले का उन्नत समाधान

आपकी क्वेरी मेरी समझ से कहीं अधिक जटिल है। आपको सभी . से अधिक चलने वाली राशि चाहिए चयनित आइटम की पंक्तियाँ, फिर आप न्यूनतम तिथि से पुरानी पंक्तियों को ट्रिम करना चाहते हैं, और पिछले महीने की पूर्व-गणना के साथ लापता महीनों को भरना चाहते हैं।

मैं इसे अब LEFT JOIN LATERAL . के साथ प्राप्त करता हूं .

SELECT COALESCE(m.yearmonth, c.yearmonth)::date, sold_qty, on_hand
FROM  (
   SELECT yearmonth
        , COALESCE(sold_qty, 0) AS sold_qty
        , sum(on_hand_mon) OVER (ORDER BY yearmonth) AS on_hand
        , lead(yearmonth)  OVER (ORDER BY yearmonth)
                                - interval '1 month' AS nextmonth
   FROM (
      SELECT date_trunc('month', c.change_date) AS yearmonth
           , sum(c.sold_qty / s.qty)::numeric(18,2) AS sold_qty
           , sum(c.on_hand) AS on_hand_mon
      FROM   item_change      c         
      LEFT   JOIN item        i USING (item_id)
      LEFT   JOIN item_size   s ON s.item_id = i.item_id AND s.name = i.sell_size
      LEFT   JOIN item_plu    p ON p.item_id = i.item_id AND p.seq_num = 0
      WHERE  c.change_date < date_trunc('month', now()) - interval '1 day'
      AND    c.item_id = (SELECT item_id FROM item_plu WHERE number = '51515')
      GROUP  BY 1
      ) sub
   ) c
LEFT   JOIN LATERAL generate_series(c.yearmonth
                                  , c.nextmonth
                                  , interval '1 month') m(yearmonth) ON TRUE
WHERE  c.yearmonth > date_trunc('year', now()) - interval '540 days'
ORDER  BY COALESCE(m.yearmonth, c.yearmonth);

SQL Fiddle न्यूनतम परीक्षण मामले के साथ।

प्रमुख बिंदु:

  • मैंने आपके व्यू को पूरी तरह से क्वेरी से हटा दिया है। बिना किसी लाभ के बहुत अधिक लागत।

  • चूंकि आप एक एकल . का चयन करते हैं item_id , आपको GROUP BY item_id करने की आवश्यकता नहीं है या PARTITION BY item_id

  • लघु तालिका उपनामों का उपयोग करें और सभी संदर्भों को स्पष्ट करें - विशेष रूप से सार्वजनिक मंच पर पोस्ट करते समय।

  • आपके जुड़ने में कोष्ठक सिर्फ शोर थे। जॉइन वैसे भी डिफ़ॉल्ट रूप से बाएं से दाएं निष्पादित होते हैं।

  • सरलीकृत तिथि सीमाएं (चूंकि मैं टाइमस्टैम्प के साथ काम करता हूं):

    date_trunc('year', current_date)  - interval '540 days'
    date_trunc('month', current_date) - interval '1 day'
    

    समकक्ष, लेकिन इससे सरल और तेज़:

    current_date - date_part('day',current_date)::integer - 540
    current_date - date_part('day',current_date)::integer
  • अब मैं generate_series() . के साथ सभी गणनाओं के बाद लापता महीनों को भरता हूं प्रति पंक्ति कॉल।

  • यह होना चाहिए LEFT JOIN LATERAL ... ON TRUE , JOIN LATERAL . का संक्षिप्त रूप नहीं अंतिम पंक्ति के कोने के मामले को पकड़ने के लिए। विस्तृत विवरण:

महत्वपूर्ण साइड नोट:

character(22) एक भयानक है प्राथमिक कुंजी के लिए डेटा प्रकार (या कोई भी कॉलम)। विवरण:

आदर्श रूप से यह एक int होगा या bigint कॉलम, या संभवतः एक UUID

साथ ही, धन राशियों को money टाइप करें या integer (सेंट का प्रतिनिधित्व) समग्र रूप से बेहतर प्रदर्शन करता है।

लंबे समय में , प्रदर्शन खराब होना तय है, क्योंकि आपको अपनी गणना में शुरुआत से ही सभी पंक्तियों को शामिल करना होगा। आपको पुरानी पंक्तियों को काट देना चाहिए और on_hold . के संतुलन को अमल में लाना चाहिए वार्षिक आधार पर या कुछ और।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. मैं गैर-संवादात्मक रूप से 'psql' के लिए पासवर्ड कैसे निर्दिष्ट करूं?

  2. डॉकर का उपयोग करते हुए, पैनिक को किसने ट्रिगर किया:एक वैध चेकपॉइंट रिकॉर्ड का पता नहीं लगा सका

  3. SQLAlchemy SSL कनेक्शन की पुष्टि करता है

  4. Postgresql:केवल तालिका कैसे बनाएं यदि यह पहले से मौजूद नहीं है?

  5. AWS-Postgres सर्वर को हरोकू होस्टिंग के साथ स्प्रिंग बूट एप्लिकेशन से कनेक्ट करने में विफल