পূর্ববর্তী এবং আসল সারি মানের উপর ভিত্তি করে সারি মান গণনা করুন


9

সবাইকে হাই এবং আপনার সহায়তার জন্য ধন্যবাদ।
আমার নিম্নলিখিত পরিস্থিতি রয়েছে: একটি সারণী যা বিবৃতিতে আইডি (ইনট), স্টেমেন্ট_ডেট (তারিখ), ডেবিট (ডাবল), ক্রেডিট (ডাবল) এবং ভারসাম্য (দ্বিগুণ) ধারণ করেআমার টেবিলের কাঠামো

আমি এই নিয়মগুলি অনুসরণ করে ভারসাম্য গণনা করতে চাই:

প্রথম সারির ভারসাম্য ( কালানুক্রমিকভাবে ) = ডেবিট - জমা এবং বাকি সারির জন্য r

বর্তমান সারি ভারসাম্য = কালানুক্রমিকভাবে আগের সারি ব্যালেন্স + বর্তমান সারি ডেবিট - বর্তমান সারি ক্রেডিট

আপনি উপরের ছবিতে দেখতে পাচ্ছেন যে সারিগুলি তারিখ অনুসারে সাজানো হয়নি এবং সেজন্য stmnt_date মানটির গুরুত্বের উপর জোর দেওয়ার জন্য আমি কালক্রমে দুটি শব্দ ব্যবহার করেছি।

আপনার সাহায্যের জন্য আপনাকে অনেক ধন্যবাদ।


আপনি কি ডেবিট এবং ক্রেডিট ক্ষেত্রগুলিকে একটি ক্ষেত্রে যোগ দিতে পারবেন? যদি তা হয় তবে আপনি ডেবিট হিসাবে নেতিবাচক মান এবং creditণ হিসাবে ইতিবাচক মানগুলি ব্যবহার করতে পারেন।
মাইক 2

1
ভবিষ্যতের প্রশ্নের জন্য (যেহেতু এটির উত্তর দেওয়া হয়েছে), পাঠ্যের ক্ষেত্রে কোড কোড প্রিন্ট-স্ক্রিন নয়। এছাড়াও অন্তর্ভুক্ত CREATE TABLEবিবৃতি এবং নমুনা তথ্য (সঙ্গে INSERT)।
ypercubeᵀᴹ

আপনার জবাব @ সাইপারকুবের প্রতি শ্রদ্ধা জানাতে, যে কেউ এটি পড়ছেন আমি dba.stackexchange.com/a/183207/131900 এর
জ্যাক মরিস

উত্তর:


8

ধরে নিই যে stmnt_dateএর UNIQUEসীমাবদ্ধতা রয়েছে, এটি উইন্ডো / বিশ্লেষণমূলক ফাংশনগুলির সাথে মোটামুটি সহজ হবে:

SELECT 
    s.stmnt_date, s.debit, s.credit,
    SUM(s.debit - s.credit) OVER (ORDER BY s.stmnt_date
                                  ROWS BETWEEN UNBOUNDED PRECEDING
                                           AND CURRENT ROW)
        AS balance
FROM
    statements AS s
ORDER BY
    stmnt_date ;

দুর্ভাগ্যক্রমে, মাইএসকিউএল (এখনও) বিশ্লেষণমূলক ফাংশন প্রয়োগ করে নি। আপনি কঠোর এসকিউএল দিয়ে, টেবিলে স্ব-যোগদানের মাধ্যমে (যা 100% কাজ করার পরিবর্তে অকার্যকর হওয়া উচিত) বা নির্দিষ্ট মাইএসকিউএল বৈশিষ্ট্য, ভেরিয়েবল (যা বেশ দক্ষ হবে তবে আপনি এটি পরীক্ষা করে দেখতে চান) দিয়ে সমস্যার সমাধান করতে পারেন either মাইএসকিএল আপগ্রেড করার সময়, ফলাফলগুলি এখনও সঠিক এবং কিছু অপ্টিমাইজেশান উন্নতি দ্বারা ম্যাঙ্গেল না হয়েছে তা নিশ্চিত করার জন্য:

SELECT 
    s.stmnt_date, s.debit, s.credit,
    @b := @b + s.debit - s.credit AS balance
FROM
    (SELECT @b := 0.0) AS dummy 
  CROSS JOIN
    statements AS s
ORDER BY
    stmnt_date ;

আপনার ডেটা সহ, এটি ফলাফল:

+------------+-------+--------+---------+
| stmnt_date | debit | credit | balance |
+------------+-------+--------+---------+
| 2014-05-15 |  3000 |      0 |    3000 |
| 2014-06-17 | 20000 |      0 |   23000 |
| 2014-07-16 |     0 |   3000 |   20000 |
| 2014-08-14 |     0 |   3000 |   17000 |
| 2015-02-01 |  3000 |      0 |   20000 |
+------------+-------+--------+---------+
5 rows in set (0.00 sec)

6

আমি মনে করি আপনি নিম্নলিখিত চেষ্টা করতে পারেন:

set @balance := 0;

SELECT stmnt_date, debit, credit, (@balance := @balance + (debit - credit)) as Balance
FROM statements
ORDER BY stmnt_date;

2

ypercube এর উত্তরটি বেশ দর্শনীয় (আমি এর আগে একটি ডামি সিলেক্টের মাধ্যমে একটি ক্যোয়ারির মধ্যে একটি পরিবর্তনশীল সৃষ্টি দেখিনি), সুতরাং আপনার সুবিধার জন্য এখানে তৈরি টেবিল বিবরণ দেওয়া আছে।

গুগল ইমেজ অনুসন্ধানে টেবুলার ডেটা চিত্রগুলির জন্য, আপনি এটি একটি পাঠ্য নথিতে রূপান্তর করতে https://convertio.co/ocr/ বা https://ocr.space/ ব্যবহার করতে পারেন । তারপরে যদি ওসিআর সঠিকভাবে কলামগুলি সনাক্ত না করে এবং আপনার কাছে ম্যাক থাকে তবে একটি আয়তক্ষেত্রাকার নির্বাচন সম্পাদন করতে এবং কলামগুলি চারপাশে সরিয়ে নিতে বিকল্প কী সহ টেক্সটরঙ্গলার ব্যবহার করুন । সিকুয়েল প্রো , টেক্সটর্যাংলারের মতো এসকিউএল সম্পাদক এবং গুগল ডক্সের মতো স্প্রেডশিটের সংমিশ্রণটি ট্যাব-বিচ্ছিন্ন ট্যাবুলার ডেটাগুলি অত্যন্ত দক্ষ করে তোলে।

আমি যদি একটি মন্তব্যটিতে এই সমস্ত কিছু রাখতে পারি, তবে দয়া করে এই উত্তরটিকে উজ্জীবিত করবেন না।

-- DROP TABLE statements;

CREATE TABLE IF NOT EXISTS statements (
  id integer NOT NULL AUTO_INCREMENT,
  stmnt_date date,
  debit integer not null default 0,
  credit integer not null default 0,
  PRIMARY KEY (id)
);

INSERT INTO statements
(stmnt_date  , debit, credit) VALUES
('2014-06-17', 20000, 0     ),
('2014-08-14', 0    , 3000  ),
('2014-07-16', 0    , 3000  ),
('2015-02-01', 3000 , 0     ),
('2014-05-15', 3000 , 0     );

-- this is slightly modified from ypercube's (@b := 0 vs @b := 0.0)
SELECT 
    s.stmnt_date, s.debit, s.credit,
    @b := @b + s.debit - s.credit AS balance
FROM
    (SELECT @b := 0) AS dummy 
CROSS JOIN
    statements AS s
ORDER BY
    stmnt_date ASC;

/* result
+------------+-------+--------+---------+
| stmnt_date | debit | credit | balance |
+------------+-------+--------+---------+
| 2014-05-15 |  3000 |      0 |    3000 |
| 2014-06-17 | 20000 |      0 |   23000 |
| 2014-07-16 |     0 |   3000 |   20000 |
| 2014-08-14 |     0 |   3000 |   17000 |
| 2015-02-01 |  3000 |      0 |   20000 |
+------------+-------+--------+---------+
5 rows in set (0.00 sec)
*/

1

বড় টেবিলগুলিতে স্ব-যোগদানের টেবিলগুলি খুব দ্রুত নয়। সুতরাং পোস্টগ্রেএসকিউএল-এ এই টাস্কটি মোকাবেলা করার জন্য আমি স্টোরেজ ফিল্ড "ব্যালেন্স" গণনা করার জন্য ট্রিগার ফাংশনটি ব্যবহার করার সিদ্ধান্ত নিয়েছি। সমস্ত গণনা প্রতিটি সারির জন্য একবারই ঘটে।

DROP TABLE IF EXISTS statements;

CREATE TABLE IF NOT EXISTS statements (
  id BIGSERIAL,
  stmnt_date TIMESTAMP,
  debit NUMERIC(18,2) not null default 0,
  credit NUMERIC(18,2) not null default 0,
  balance NUMERIC(18,2)
);

CREATE OR REPLACE FUNCTION public.tr_fn_statements_balance()
RETURNS trigger AS
$BODY$
BEGIN

    UPDATE statements SET
    balance=(SELECT SUM(a.debit)-SUM(a.credit) FROM statements a WHERE a.stmnt_date<=statements.stmnt_date)
    WHERE stmnt_date>=NEW.stmnt_date;

RETURN NULL;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

CREATE TRIGGER tr_statements_after_update
  AFTER INSERT OR UPDATE OF debit, credit
  ON public.statements
  FOR EACH ROW
  EXECUTE PROCEDURE public.tr_fn_statements_balance();


INSERT INTO statements
(stmnt_date  , debit, credit) VALUES
('2014-06-17', 20000, 0     ),
('2014-08-14', 0    , 3000  ),
('2014-07-16', 0    , 3000  ),
('2015-02-01', 3000 , 0     ),
('2014-05-15', 3000 , 0     );


select * from statements order by stmnt_date;

-1

উদাহরণস্বরূপ, এমএসএসকিউএল:

সিটিই উত্পন্ন করতে একটি () সহ বিবৃতি ব্যবহার করুন। এটি মূলত একটি অস্থায়ী ফলাফল সেট যা প্রতিটি সারিটির মান প্রদর্শন করবে। আপনি শেষে একটি কলাম তৈরি করতে স্টেটমেন্ট সহ গণিতটি ব্যবহার করতে পারেন, সারির মোটটি ডেবিট-ক্রেডিট দেখানোর জন্য গণিত ব্যবহার করে। আপনার বিবৃতি সহ আপনাকে প্রতিটি সারিতে সারি সংখ্যা নির্ধারণ করতে হবে, stmnt_date দ্বারা অর্ডার করতে ওভারের ধারাটি ব্যবহার করুন ()।

তারপরে, পুনরাবৃত্তভাবে a.ROWNUMBER = b.ROWNUMBER-1 বা +1 ব্যবহার করে টেবিলটিতে নিজেকে যুক্ত করুন যা আপনাকে এই সারির a.total + b.total = মোট এবং পূর্ববর্তী সারির রেফারেন্স দিতে দেয়।

আমি প্রশংসা করি আমি কোডটি সরবরাহ করছি না তবে এটি অর্জনের এটি ব্যবহারিক পদ্ধতি। অনুরোধ করা হলে আমি কোড সরবরাহ করতে পারি :)


1
প্রশ্নটি মাইএসকিউএল সম্পর্কে। যদিও এটি DBMS- তে সিটিই বা উইন্ডো ফাংশনগুলির সাথে কীভাবে করা যেতে পারে তার কোড সরবরাহ করা খারাপ নয় (বিপরীতে) (পোস্টগ্রিস, এসকিউএল-সার্ভার, ডিবি 2, ওরাকল, ... তালিকাটি দীর্ঘ), আপনি কমপক্ষে মাইএসকিউএল এ কীভাবে করা যায় সে সম্পর্কে কমপক্ষে কোড সরবরাহ করা উচিত।
ypercubeᵀᴹ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.