আমার পূর্বসূরীর বংশধরের গভীরতা গণনা করা দরকার। যখন কোনও রেকর্ড থাকে তখন object_id = parent_id = ancestor_id
এটিকে মূল নোড (পূর্বপুরুষ) হিসাবে বিবেচনা করা হয়। আমি WITH RECURSIVE
পোস্টগ্রিজ এসকিউএল 9.4 দিয়ে চলছে এমন একটি কোয়েরি পাওয়ার চেষ্টা করছি ।
আমি ডেটা বা কলামগুলি নিয়ন্ত্রণ করি না। ডেটা এবং টেবিল স্কিমা একটি বাহ্যিক উত্স থেকে আসে। টেবিলটি ক্রমাগত বাড়ছে । এখন প্রতিদিন 30k রেকর্ড দ্বারা। গাছের কোনও নোড অনুপস্থিত হতে পারে এবং এগুলি কোনও পর্যায়ে কোনও বাহ্যিক উত্স থেকে টেনে নেওয়া হবে। এগুলি সাধারণত created_at DESC
ক্রমে টানা হয় তবে ডেটাটি অ্যাসিক্রোনাস ব্যাকগ্রাউন্ড কাজের সাথে টানা হয়।
আমাদের প্রাথমিকভাবে এই সমস্যার একটি কোড সমাধান ছিল, তবে এখন 5M + সারি রয়েছে, এটি সম্পূর্ণ হতে প্রায় 30 মিনিট সময় নেয়।
সারণির সংজ্ঞা এবং পরীক্ষার ডেটা উদাহরণ:
CREATE TABLE objects (
id serial NOT NULL PRIMARY KEY,
customer_id integer NOT NULL,
object_id integer NOT NULL,
parent_id integer,
ancestor_id integer,
generation integer NOT NULL DEFAULT 0
);
INSERT INTO objects(id, customer_id , object_id, parent_id, ancestor_id, generation)
VALUES (2, 1, 2, 1, 1, -1), --no parent yet
(3, 2, 3, 3, 3, -1), --root node
(4, 2, 4, 3, 3, -1), --depth 1
(5, 2, 5, 4, 3, -1), --depth 2
(6, 2, 6, 5, 3, -1), --depth 3
(7, 1, 7, 7, 7, -1), --root node
(8, 1, 8, 7, 7, -1), --depth 1
(9, 1, 9, 8, 7, -1); --depth 2
নোট যে object_id
অনন্য নয়, তবে সংমিশ্রণটি (customer_id, object_id)
অনন্য।
এই জাতীয় একটি ক্যোয়ারী চালানো:
WITH RECURSIVE descendants(id, customer_id, object_id, parent_id, ancestor_id, depth) AS (
SELECT id, customer_id, object_id, parent_id, ancestor_id, 0
FROM objects
WHERE object_id = parent_id
UNION
SELECT o.id, o.customer_id, o.object_id, o.parent_id, o.ancestor_id, d.depth + 1
FROM objects o
INNER JOIN descendants d ON d.parent_id = o.object_id
WHERE
d.id <> o.id
AND
d.customer_id = o.customer_id
) SELECT * FROM descendants d;
আমি generation
কলামটি গণনা করা গভীরতা হিসাবে সেট করতে চাই । একটি নতুন রেকর্ড যুক্ত করা হলে, প্রজন্মের কলামটি -1 হিসাবে সেট করা থাকে। কিছু ঘটনা আছে যেখানে একটি parent_id
এখনও টানা নাও পারে। যদি এটি parent_id
বিদ্যমান না থাকে তবে এটি প্রজন্মের কলামটি -1 এ সেট করা উচিত।
চূড়ান্ত তথ্য দেখতে হবে:
id | customer_id | object_id | parent_id | ancestor_id | generation
2 1 2 1 1 -1
3 2 3 3 3 0
4 2 4 3 3 1
5 2 5 4 3 2
6 2 6 5 3 3
7 1 7 7 7 0
8 1 8 7 7 1
9 1 9 8 7 2
ক্যোয়ারির ফলাফলটি প্রজন্মের কলামটি সঠিক গভীরতায় আপডেট করা উচিত।
আমি থেকে কাজ শুরু করে তাই এই সম্পর্কিত প্রশ্নের উত্তর ।
update
আপনার পুনরাবৃত্তি সিটিই ফলাফল সঙ্গে টেবিলে চান ?