পোস্টগ্রিজ এসকিউএলে সংখ্যার যোগফল গণনা করা হচ্ছে


87

আমি ক্ষেত্রের পরিমাণ বা চলমান পরিমাণ সন্ধান করতে এবং এটি টেবিলে মঞ্চ থেকে সন্নিবেশ করতে চাই। আমার মঞ্চের কাঠামোটি এরকম কিছু:

ea_month    id       amount    ea_year    circle_id
April       92570    1000      2014        1
April       92571    3000      2014        2
April       92572    2000      2014        3
March       92573    3000      2014        1
March       92574    2500      2014        2
March       92575    3750      2014        3
February    92576    2000      2014        1
February    92577    2500      2014        2
February    92578    1450      2014        3          

আমি চাই আমার টার্গেট টেবিলটি এর মতো দেখতে চাই:

ea_month    id       amount    ea_year    circle_id    cum_amt
February    92576    1000      2014        1           1000 
March       92573    3000      2014        1           4000
April       92570    2000      2014        1           6000
February    92577    3000      2014        2           3000
March       92574    2500      2014        2           5500
April       92571    3750      2014        2           9250
February    92578    2000      2014        3           2000
March       92575    2500      2014        3           4500
April       92572    1450      2014        3           5950

এই ফলাফলটি অর্জনে কীভাবে যেতে হবে তা নিয়ে আমি সত্যিই খুব বিভ্রান্ত। পোস্টগ্র্রেএসকিউএল ব্যবহার করে আমি এই ফলাফলটি অর্জন করতে চাই।

এই ফলাফল-সেটটি অর্জন করতে কীভাবে কেউ পরামর্শ দিতে পারেন?


4
আপনি কীভাবে আপনার টার্গেট সারণীতে 1000 এর কাম_মামেন্ট পাবেন? চেনাশোনা_আইডির জন্য, এই পরিমাণটি 2000 বলে মনে হচ্ছে

উত্তর:


132

মূলত, আপনার একটি উইন্ডো ফাংশন প্রয়োজন । আজকাল এটি একটি আদর্শ বৈশিষ্ট্য। খাঁটি উইন্ডো ফাংশন ছাড়াও, আপনি কোনও ক্লজ যুক্ত করে পোস্টগ্রিসে উইন্ডো ফাংশন হিসাবে যে কোনও মোট ফাংশন ব্যবহার করতে পারেন OVER

এখানে বিশেষ অসুবিধা হ'ল পার্টিশন পাওয়া এবং ক্রমটি সঠিকভাবে সাজানো:

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id
                         ORDER BY ea_year, ea_month) AS cum_amt
FROM   tbl
ORDER  BY circle_id, month;

এবং না GROUP BY

প্রতিটি সারির যোগফল পার্টিশনের প্রথম সারি থেকে বর্তমান সারিতে গণনা করা হয় - বা ম্যানুয়ালটিকে যথাযথ হিসাবে উদ্ধৃত করা :

ডিফল্ট ফ্রেমিং অপশনটি হ'ল RANGE UNBOUNDED PRECEDINGযা একই RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW। এর সাথে ORDER BY, এটি বর্তমান সারির শেষ ORDER BYপিয়ারের মধ্য দিয়ে পার্টিশন থেকে সমস্ত সারি হিসাবে ফ্রেম সেট করে ।

... যা আপনার পরে সংখ্যামূলক বা চলমান যোগফল। বোল্ড জোর আমার।

একই সঙ্গে সারি (circle_id, ea_year, ea_month)হয় "সহকর্মীরা" এই প্রশ্নের সাথে হবে। যারা প্রত্যেকে যোগফলের সাথে যোগ করা সমস্ত সমবয়সীদের সাথে একই চলমান যোগফল দেখায়। তবে আমি ধরে নিই যে আপনার টেবিলটি UNIQUEচালু আছে (circle_id, ea_year, ea_month), তার পরে বাছাইয়ের ক্রমটি ডিটারমিনিস্টিক এবং কোনও সারিতে পিয়ার নেই।

এখন, ORDER BY ... ea_month মাসের নামের জন্য স্ট্রিং দিয়ে কাজ করবে না । পোস্টগ্রিজ লোকাল সেটিং অনুসারে বর্ণমালা অনুসারে বাছাই করবে।

dateআপনার টেবিলে যদি সত্যিকারের মান সঞ্চিত থাকে তবে আপনি সঠিকভাবে বাছাই করতে পারেন। যদি না হয়, আমি প্রতিস্থাপন করতে সুপারিশ ea_yearএবং ea_monthএকটি একক কলাম সঙ্গে monধরনের dateআপনার টেবিল হবে।

  • আপনার সাথে যা আছে তা রূপান্তর করুন to_date():

      to_date(ea_year || ea_month , 'YYYYMonth') AS mon
    
  • প্রদর্শনের জন্য, আপনি এর সাথে মূল স্ট্রিংগুলি পেতে পারেন to_char():

      to_char(mon, 'Month') AS ea_month
      to_char(mon, 'YYYY') AS ea_year
    

দুর্ভাগ্যজনক ডিজাইনের সাথে আটকে থাকাকালীন, এটি কাজ করবে:

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id ORDER BY mon) AS cum_amt
FROM   (SELECT *, to_date(ea_year || ea_month, 'YYYYMonth') AS mon FROM tbl)
ORDER  BY circle_id, mon;

সমাধানের জন্য ধন্যবাদ .. আপনি কি আমাকে আরও একটি জিনিস সাহায্য করতে পারেন। আমি একই জিনিসটি বাস্তবায়িত করতে চাই যুক্তিযুক্ত যুক্তি দিয়ে প্রতিটি বৃত্তের এক বছরের এক মাসের জন্য কেবল একটি রেকর্ড থাকবে। এবং এই ফাংশনটি প্রতি মাসে একবার চালানোর কথা রয়েছে। আমি কীভাবে এটি অর্জন করতে পারি?
ইউসুফ সুলতান

4
@ ইউসুফসুলতান: বেশিরভাগ সময় কার্সারের চেয়ে ভাল সমাধান হতে পারে। এটি অবশ্যই একটি নতুন প্রশ্নের জন্য স্টাফ। একটি নতুন প্রশ্ন শুরু করুন।
এরউইন ব্র্যান্ডসটেটার

আমি এই উত্তরটি কমপক্ষে একটি নোট ছাড়া এখানে অসম্পূর্ণ দেখতে পাচ্ছি যে এখানে "ফ্রেমিং" চলছে যা ডিফল্ট range unbounded preceding, যা একই রকম range between unbounded preceding and current row। এ কারণেই sum()যখন উইন্ডো ফাংশন হিসাবে ব্যবহৃত হয় এটি একটি চলমান মোট উত্পাদন করে - অন্য উইন্ডো ফাংশনগুলিতে এই ডিফল্ট ফ্রেম থাকে না।
কলিন টি হার্ট

4
@ কলিনটহার্ট: আমি স্পষ্ট করতে উপরে আরও কিছু যুক্ত করেছি।
এরউইন ব্র্যান্ডসটেটার

এখানে একটি সাধারণ প্রশ্নের সাথে একই ধরণের প্রশ্নের লিঙ্ক রয়েছে ( PARTITIONচলমান মোট তৈরির জন্য সর্বদা প্রয়োজন হয় না): stackoverflow.com/a/5700744/175830
জেসন অ্যাকসেলসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.