आम तौर पर आपको बुनियादी बातों का अध्ययन करने . की आवश्यकता होती है , इससे पहले कि आप प्रश्न पूछना शुरू करें।CREATE FUNCTION
, PL/pgSQL
और SQL फ़ंक्शन
।
प्रमुख बिंदु क्यों उदाहरण बकवास है
-
सबसे पहले, आप एक पहचानकर्ता . को सौंप नहीं सकते जैसे आप करते हैं। सादे एसक्यूएल में पहचानकर्ताओं को पैरामीटर नहीं किया जा सकता है। आपको चाहिए गतिशील एसक्यूएल उसके लिए।
बेशक, आपको अपनी आवश्यकताओं के अनुसार वास्तव में इसकी आवश्यकता नहीं है। इसमें केवल एक टेबल शामिल है। कोशिश करना और इसे पैरामीटर बनाना बकवास है। -
पहचानकर्ता के रूप में प्रकार के नामों का उपयोग न करें। मैं
_date
का उपयोग करता हूंdate
. के बजाय पैरामीटर नाम के रूप में और अपने टेबल कॉलम का नाम बदलकरasset_date
. कर दिया .ALTER
तदनुसार आपकी तालिका परिभाषा। -
किसी तालिका से डेटा लाने वाला फ़ंक्शन कभी भी
IMMUTABLE
नहीं हो सकता है . मैनुअल पढ़ें। -
आप निरर्थक तरीकों से plpgsql तत्वों के साथ SQL सिंटैक्स का मिश्रण कर रहे हैं।
WITH
एकSELECT
का हिस्सा है कथन और plpgsql नियंत्रण संरचनाओं जैसेLOOP
. के साथ मिश्रित नहीं किया जा सकता है याIF
।
उचित कार्य
एक उचित कार्य इस तरह दिख सकता है (कई तरीकों में से एक):
CREATE FUNCTION percentage_change_func(_asset_symbol text)
RETURNS TABLE(asset_date date, price numeric, pct_change numeric) AS
$func$
DECLARE
last_price numeric;
BEGIN
FOR asset_date, price IN
SELECT a.asset_date, a.price
FROM asset_histories a
WHERE a.asset_symbol = _asset_symbol
ORDER BY a.asset_date -- traverse ascending
LOOP
pct_change := price / last_price; -- NULL if last_price is NULL
RETURN NEXT;
last_price := price;
END LOOP;
END
$func$ LANGUAGE plpgsql STABLE
प्रदर्शन इतना खराब नहीं होना चाहिए, लेकिन यह केवल व्यर्थ की जटिलता है।
उचित समाधान:सादा प्रश्न
सबसे आसान (और शायद सबसे तेज़) तरीका विंडो फ़ंक्शन के साथ होगा <मजबूत>lag()
:
SELECT asset_date, price
,price / lag(price) OVER (ORDER BY asset_date) AS pct_change
FROM asset_histories
WHERE asset_symbol = _asset_symbol
ORDER BY asset_date;
मानक विचलन
आपकी बाद की टिप्पणी के अनुसार, आप मानक विचलन जैसे सांख्यिकीय संख्याओं की गणना करना चाहते हैं।
समर्पित हैं आँकड़ों के लिए समग्र कार्य
PostgreSQL में।