আমি কীভাবে সম্প্রসারিত গাছের মতো ফ্যাশনে পুনরাবৃত্ত ক্যোয়ারির ফলাফলগুলি বাছাই করব?


12

ধরে নেওয়া যাক আপনার nodesযেমন একটি টেবিল আছে :

CREATE TABLE nodes
(
    node serial PRIMARY KEY,
    parent integer NULL REFERENCES nodes(node),
    ts timestamp NOT NULL DEFAULT now()
);

এটি শীর্ষে মূল নোড এবং মূল নোড বা অন্যান্য শিশু নোডগুলি থেকে জড়িত বেশ কয়েকটি শিশু নোড সহ একটি আদর্শ নোডের মতো গাছের কাঠামোর প্রতিনিধিত্ব করে।

আসুন কয়েকটি উদাহরণ মান সন্নিবেশ করান:

INSERT INTO nodes (parent)
VALUES (NULL), (NULL), (NULL), (NULL), (1), (1), (1), (1), (6), (1)
     , (6), (9), (6), (6), (3), (3), (3), (15);

এখন আমি প্রথম 10 টি মূল নোড এবং তাদের সমস্ত বাচ্চাদের 4 এর গভীরতা পর্যন্ত পুনরুদ্ধার করতে চাই:

WITH RECURSIVE node_rec AS
(
    (SELECT 1 AS depth, * FROM nodes WHERE parent IS NULL LIMIT 10)

    UNION ALL

    SELECT depth + 1, n.*
    FROM nodes AS n JOIN node_rec ON (n.parent = node_rec.node)
    WHERE depth < 4
)
SELECT * FROM node_rec;

এটি দুর্দান্ত কাজ করে এবং আমাকে নিম্নলিখিত ফলাফল দেয়:

 depth | node | parent 
-------+------+--------
     1 |  1   |
     1 |  2   |
     1 |  3   |
     1 |  4   |
     2 |  5   |  1
     2 |  6   |  1
     2 |  7   |  1
     2 |  8   |  1
     2 | 10   |  1
     2 | 15   |  3
     2 | 16   |  3
     2 | 17   |  3
     3 |  9   |  6
     3 | 11   |  6
     3 | 13   |  6
     3 | 14   |  6
     3 | 18   | 15
     4 | 12   |  9

আপনি যেমন খেয়াল করেছেন, এর কোনও ORDER BYধারা নেই, সুতরাং অর্ডারটি সংজ্ঞায়িত করা হয়নি। আপনি এখানে যে ক্রমটি দেখতে পাচ্ছেন তা হ'ল মূল নোড থেকে গভীর নোড।

নীচের উদাহরণের চিত্র থেকে আপনি দেখতে পাবেন যে কীভাবে ফলাফলগুলি সেগুলি প্রসারিত বৃক্ষের দৃশ্যে প্রদর্শিত হবে?

নোডের প্রসারিত গাছের দৃশ্য

আমি মূলত চান শিশু নোডগুলি তাদের সংশ্লিষ্ট প্যারেন্ট নোডের ঠিক পরে স্থাপন করা উচিত। যদি দুটি বা ততোধিক শিশু নোডের একই প্যারেন্ট নোড থাকে তবে আমি চাই যে সেগুলি তাদের টাইমস্ট্যাম্প অনুসারে বাছাই করা হোক। উপরের উদাহরণের উপর ভিত্তি করে, এখানে কাঙ্ক্ষিত আউটপুট ক্রম যা আমি অর্জন করার চেষ্টা করছি:

 depth | node | parent | ts
-------+------+--------+---------
     1 |  1   |        | 2014-01-01 00:00:00
     2 |  5   |     1  | 2014-01-01 00:10:00
     2 |  6   |     1  | 2014-01-01 00:20:00
     3 |  9   |     6  | 2014-01-01 00:25:00
     4 |  12  |     9  | 2014-01-01 00:27:00
     3 |  11  |     6  | 2014-01-01 00:26:00
     3 |  13  |     6  | 2014-01-01 00:30:00
     3 |  14  |     6  | 2014-01-01 00:36:00
     2 |  7   |     1  | 2014-01-01 00:21:00
     2 |  8   |     1  | 2014-01-01 00:22:00
     2 |  10  |     1  | 2014-01-01 00:23:00
     1 |  2   |        | 2014-01-01 00:08:00
     1 |  3   |        | 2014-01-01 00:09:00
     2 |  15  |     3  | 2014-01-01 10:00:00
     3 |  18  |     15 | 2014-01-01 11:05:00
     2 |  16  |     3  | 2014-01-01 11:00:00
     2 |  17  |     3  | 2014-01-01 12:00:00
     1 |  4   |        | 2014-01-01 00:10:00

কেউ কি আমাকে এখানে ব্যাখ্যা করতে পারেন যে depthকলামটি এসেছে? আমি এটি প্রাথমিক টেবিল কাঠামোতে দেখছি না।
সোমিন

@ সোরিন, আমি জানি এটি একটি সত্যিকারের পুরানো পোস্ট, তবে আমি গুগলে এটিকে হোঁচট খেয়েছি এবং ভেবেছি আপনার প্রশ্নের উত্তরটি দিয়েছি। গভীরতা প্রথম ক্যোয়ারির আক্ষরিক '1' এর নাম থেকে আসে।
স্যাম

উত্তর:


11

মূল থেকে শুরু করে পাত পর্যন্ত পথের প্রতিনিধিত্বকারী একটি অ্যারে পছন্দসই ক্রমানুসারে অর্ডার অর্জন করবে:

WITH RECURSIVE node_rec AS (
   (SELECT 1 AS depth, ARRAY[node] AS path, *
    FROM   nodes
    WHERE  parent IS NULL
    LIMIT  10
   )    
    UNION ALL
    SELECT r.depth + 1, r.path || n.node, n.*
    FROM   node_rec r 
    JOIN   nodes    n ON n.parent = r.node
    WHERE  r.depth < 4
)
SELECT *
FROM   node_rec
ORDER  BY path;

যদি দুটি বা ততোধিক শিশু নোডের একই প্যারেন্ট নোড থাকে তবে আমি চাই যে সেগুলি তাদের টাইমস্ট্যাম্প অনুসারে বাছাই করা হোক।

রুটটির দিকে এক এক করে পাথটি স্থানান্তর করুন এবং সেই কলামটি অতিরিক্তভাবে ক্রম করুন:

WITH RECURSIVE node_rec AS (
   (SELECT 1 AS depth, ARRAY[node] AS path, *
    FROM   nodes
    WHERE  parent IS NULL
    LIMIT  10
   )    
    UNION ALL
    SELECT r.depth + 1, r.path || n.parent, n.*
    FROM   node_rec r 
    JOIN   nodes    n ON n.parent = r.node
    WHERE  r.depth < 4
)
SELECT *
FROM   node_rec
ORDER  BY path, ts;

ধন্যবাদ, এটি দুর্দান্ত কাজ করে! যাইহোক, "যদি দুটি বা ততোধিক শিশু নোডের একই প্যারেন্ট নোড থাকে তবে আমি কী চাই যে সেগুলি তাদের টাইমস্ট্যাম্প" অংশ অনুসারে বাছাই করা যায়? এই পদ্ধতির সাথে এটি কি করণীয়? উচ্চতর নোড আইডি পরবর্তী সময়ের সাথে মিলে যায় এমনটা সবসময়ই না ঘটে।
জনক্যান্ড

@ জনক্যান্ড: আপনি রুটটির দিকে এক এক করে পাথটি স্থানান্তর করতে পারবেন (প্রথম অবস্থানে মূল নোডটি পুনরাবৃত্তি করুন!) এবং সেই কলাম দ্বারা অতিরিক্ত অর্ডারও করতে পারেন ...
এরউইন ব্র্যান্ডসটেটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.