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

पोस्टग्रेज में पिछली पंक्ति का कॉलम मान प्राप्त करें अद्यतन में विंडो फ़ंक्शन का उपयोग नहीं कर सकता

ऐसा मानते हुए...

  • gwma_duration और अवधि टाइपो के कारण एक ही कॉलम और अलग-अलग माना जाता है।

  • आप order_column . नामक कॉलम से ऑर्डर करना चाहते हैं . अपने वास्तविक कॉलम से बदलें।

  • आपका प्राथमिक कुंजी कॉलम है res_id . अपने वास्तविक कॉलम से बदलें।

सुअर पर लिपस्टिक लगाएं:

आपका प्रक्रियात्मक कोड तैयार और बेहतर किया गया:

CREATE OR REPLACE FUNCTION vin_calc()
  RETURNS void AS
$func$
DECLARE
   r res%rowtype;
   i integer := 0;
   last_grp text;
BEGIN

FOR r IN
   SELECT * FROM res
LOOP
   IF last_grp <> r.prod_grp_nm THEN
      i := 1;
   ELSE
      i := i + 1;
   END IF;

   IF i < 3 THEN
      UPDATE res
      SET    duration = i - 1
      WHERE  dur = r.dur
      AND    prod_grp_nm = r.prod_grp_nm
      AND    week_end = r.week_end;

   ELSE
      UPDATE res r1
      SET    duration = r.dur * 0.125 + 
            (SELECT 0.875 * gwma_duration FROM res
             WHERE order_column < r1.order_column
             ORDER BY order_column
             LIMIT 1
            )  -- could be replaced with last_duration, analog to last_grp
      WHERE  r1.dur = r.dur
      AND    r1.prod_grp_nm = r.prod_grp_nm
      AND    r1.week_end = r.week_end;
   END IF;

   last_grp := r.prod_grp_nm;

   END LOOP;
END
$func$
LANGUAGE plpgsql;
  • <के निहित कर्सर का उपयोग करें कोड>के लिए लूप . स्पष्ट स्पष्ट कर्सर की कोई आवश्यकता नहीं है।

  • भाषा का नाम कभी भी उद्धृत न करें plpgsql , जो एक पहचानकर्ता है, स्ट्रिंग नहीं।

  • कई जगहों पर अपने तर्क को सरल बनाया।

  • सबसे महत्वपूर्ण , जैसा कि त्रुटि संदेश आपको बताता है, आप SET . में विंडो फ़ंक्शन का उपयोग नहीं कर सकते हैं एक अद्यतन का खंड . मैंने इसे एक सहसंबंधित सबक्वायरी से बदल दिया। लेकिन शायद इसे last_duration . से बदला जा सकता है , last_grp . के अनुरूप :पिछले पुनरावृत्ति के मूल्य को याद रखें।

उचित समाधान

हालांकि, जब आप इसे एकल अपडेट में कर सकते हैं, तो उपरोक्त सभी बहुत अक्षम हैं कथन :

UPDATE res r
SET    duration = CASE WHEN r0.rn < 3
                     THEN r0.rn - 1
                     ELSE r0.last_dur * 0.875 + r.dur * 0.125
                  END
FROM  (
   SELECT res_id, duration
        , row_number()  OVER (PARTITION BY prod_grp_nm ORDER BY order_column) AS rn
        , lag(duration) OVER (PARTITION BY prod_grp_nm ORDER BY order_column) AS last_dur
   FROM res
   ) r0
WHERE  r.res_id = r0.res_id
  • स्पष्ट होने के लिए:आप कर सकते हैं FROM . में विंडो फ़ंक्शन का उपयोग करें खंड - कम से कम पोस्टग्रेज के आधुनिक संस्करणों में।

  • row_number() का इस्तेमाल करें , नहीं <स्ट्राइक>रैंक() आपके प्रक्रियात्मक कोड के समतुल्य होने के लिए।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. पीजी-वादे के साथ बड़े पैमाने पर आवेषण

  2. संयोजन मतभेदों को पोस्टग्रेज करता है। ओएसएक्स वी उबंटू

  3. सी ++ का उपयोग कर libpq के साथ त्रुटि लिंक करें

  4. Django PostgreSQL डेटाबेस को रीसेट करने का आसान तरीका?

  5. plpgsql में परेशान करने वाले नोटिस कम करें