শ্রেণিবদ্ধ ক্ষেত্রের সর্বোচ্চ স্তর সন্ধান করুন: সিটিই ছাড়াই বনাম


58

দ্রষ্টব্য: এই প্রশ্নটি প্রতিফলিত করার জন্য আপডেট করা হয়েছে যে আমরা বর্তমানে মাইএসকিউএল ব্যবহার করছি, এটি করার পরে, আমি যদি একটি সিটিই-সমর্থনকারী ডাটাবেস পরিবর্তন করি তবে এটি কতটা সহজ হবে তা আমি দেখতে চাই।

আমার কাছে একটি প্রাথমিক কী idএবং একটি বিদেশী কী সহ একটি স্ব-রেফারেন্সিং টেবিল রয়েছে parent_id

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment | 
| parent_id  | int(11)      | YES  |     | NULL    |                | 
| name       | varchar(255) | YES  |     | NULL    |                | 
| notes      | text         | YES  |     | NULL    |                | 
+------------+--------------+------+-----+---------+----------------+

দেওয়া হল name, আমি কীভাবে শীর্ষ স্তরের পিতামাতাকে জিজ্ঞাসা করতে পারি?

একটি দেওয়া হল name, আমি কীভাবে idরেকর্ডের সাথে যুক্ত সমস্ত জিজ্ঞাসা করতে পারি name = 'foo'?

প্রসঙ্গ: আমি একটি ডিবিএ নই, তবে এই জাতীয় শ্রেণিবিন্যাসের কাঠামোটি বাস্তবায়নের জন্য কোনও ডিবিএকে জিজ্ঞাসা করার পরিকল্পনা করছি এবং কিছু প্রশ্নের পরীক্ষা করতে চাই। এটি করার অনুপ্রেরণাটি কেটজ এট আল 2011 দ্বারা বর্ণনা করা হয়েছে ।


এখানে টেবিলের মধ্যে আইডির মধ্যে সম্পর্কের উদাহরণ রয়েছে:

এখানে চিত্র বর্ণনা লিখুন

-- -----------------------------------------------------
-- Create a new database called 'testdb'
-- -----------------------------------------------------
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

CREATE SCHEMA IF NOT EXISTS `testdb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
USE `testdb` ;

-- -----------------------------------------------------
-- Table `testdb`.`observations`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `testdb`.`observations` (
  `id` INT NOT NULL ,
  `parent_id` INT NULL ,
  `name` VARCHAR(45) NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

-- -----------------------------------------------------
-- Add Example Data Set
-- -----------------------------------------------------


INSERT INTO observations VALUES (1,3), (2,5), (3,NULL), (4,10), 
   (5,NULL), (6,1), (7,5), (8,10), (9,10), (10,3);

4
মাইএসকিউএল "প্রায় সমস্ত ডিবিএমএস" স্টেটমেন্টের ব্যতিক্রম। এটি পুনরাবৃত্ত অনুসন্ধানগুলি সমর্থন করে না। আপনার একমাত্র সুযোগ হ'ল একটি সঞ্চিত প্রক্রিয়া লিখুন যা গাছের মাধ্যমে পুনরাবৃত্তি করে এবং তথ্য পুনরুদ্ধার করে। বা - যদি স্তরের সংখ্যা সীমিত হয় - স্ব-যোগদানের অ্যাপোরিয়েট নম্বরটি ব্যবহার করুন
a_horse_with_no_name

উত্তর:


63

আপনাকে অবশ্যই মাইএসকিউএল সঞ্চিত প্রক্রিয়া ভাষার মাধ্যমে এটি স্ক্রিপ্ট করতে হবে

এখানে GetParentIDByIDঅনুসন্ধানের জন্য একটি আইডি দেওয়া একটি প্যারেন্টআইডি পুনরুদ্ধার করার জন্য কল করা একটি সঞ্চিত ফাংশন

DELIMITER $$
DROP FUNCTION IF EXISTS `junk`.`GetParentIDByID` $$
CREATE FUNCTION `junk`.`GetParentIDByID` (GivenID INT) RETURNS INT
DETERMINISTIC
BEGIN
    DECLARE rv INT;

    SELECT IFNULL(parent_id,-1) INTO rv FROM
    (SELECT parent_id FROM pctable WHERE id = GivenID) A;
    RETURN rv;
END $$
DELIMITER ;

GetAncestryপ্রথম প্রজন্ম থেকে শুরু করে প্যারেন্টআইডিগুলির একটি তালিকা পুনরুদ্ধার করার জন্য এখানে একটি স্টোরকৃত ফাংশন বলা হয় যা শুরু করার জন্য একটি আইডি দিয়ে দেওয়া সমস্ত স্তরক্রমকে আপ করা হয়:

DELIMITER $$
DROP FUNCTION IF EXISTS `junk`.`GetAncestry` $$
CREATE FUNCTION `junk`.`GetAncestry` (GivenID INT) RETURNS VARCHAR(1024)
DETERMINISTIC
BEGIN
    DECLARE rv VARCHAR(1024);
    DECLARE cm CHAR(1);
    DECLARE ch INT;

    SET rv = '';
    SET cm = '';
    SET ch = GivenID;
    WHILE ch > 0 DO
        SELECT IFNULL(parent_id,-1) INTO ch FROM
        (SELECT parent_id FROM pctable WHERE id = ch) A;
        IF ch > 0 THEN
            SET rv = CONCAT(rv,cm,ch);
            SET cm = ',';
        END IF;
    END WHILE;
    RETURN rv;
END $$
DELIMITER ;

নমুনা ডেটা উত্পন্ন করার জন্য এখানে কিছু দেওয়া হয়েছে:

USE junk
DROP TABLE IF EXISTS pctable;
CREATE TABLE pctable
(
    id INT NOT NULL AUTO_INCREMENT,
    parent_id INT,
    PRIMARY KEY (id)
) ENGINE=MyISAM;
INSERT INTO pctable (parent_id) VALUES (0);
INSERT INTO pctable (parent_id) SELECT parent_id+1 FROM pctable;
INSERT INTO pctable (parent_id) SELECT parent_id+2 FROM pctable;
INSERT INTO pctable (parent_id) SELECT parent_id+3 FROM pctable;
INSERT INTO pctable (parent_id) SELECT parent_id+4 FROM pctable;
INSERT INTO pctable (parent_id) SELECT parent_id+5 FROM pctable;
SELECT * FROM pctable;

এটি যা উত্পন্ন করে তা এখানে:

mysql> USE junk
Database changed
mysql> DROP TABLE IF EXISTS pctable;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE pctable
    -> (
    ->     id INT NOT NULL AUTO_INCREMENT,
    ->     parent_id INT,
    ->     PRIMARY KEY (id)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO pctable (parent_id) VALUES (0);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO pctable (parent_id) SELECT parent_id+1 FROM pctable;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> INSERT INTO pctable (parent_id) SELECT parent_id+2 FROM pctable;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> INSERT INTO pctable (parent_id) SELECT parent_id+3 FROM pctable;
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> INSERT INTO pctable (parent_id) SELECT parent_id+4 FROM pctable;
Query OK, 8 rows affected (0.01 sec)
Records: 8  Duplicates: 0  Warnings: 0

mysql> INSERT INTO pctable (parent_id) SELECT parent_id+5 FROM pctable;
Query OK, 16 rows affected (0.00 sec)
Records: 16  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM pctable;
+----+-----------+
| id | parent_id |
+----+-----------+
|  1 |         0 |
|  2 |         1 |
|  3 |         2 |
|  4 |         3 |
|  5 |         3 |
|  6 |         4 |
|  7 |         5 |
|  8 |         6 |
|  9 |         4 |
| 10 |         5 |
| 11 |         6 |
| 12 |         7 |
| 13 |         7 |
| 14 |         8 |
| 15 |         9 |
| 16 |        10 |
| 17 |         5 |
| 18 |         6 |
| 19 |         7 |
| 20 |         8 |
| 21 |         8 |
| 22 |         9 |
| 23 |        10 |
| 24 |        11 |
| 25 |         9 |
| 26 |        10 |
| 27 |        11 |
| 28 |        12 |
| 29 |        12 |
| 30 |        13 |
| 31 |        14 |
| 32 |        15 |
+----+-----------+
32 rows in set (0.00 sec)

এখানে প্রতিটি মানের জন্য ফাংশনগুলি উত্পন্ন করে:

mysql> SELECT id,GetParentIDByID(id),GetAncestry(id) FROM pctable;
+----+---------------------+-----------------+
| id | GetParentIDByID(id) | GetAncestry(id) |
+----+---------------------+-----------------+
|  1 |                   0 |                 |
|  2 |                   1 | 1               |
|  3 |                   2 | 2,1             |
|  4 |                   3 | 3,2,1           |
|  5 |                   3 | 3,2,1           |
|  6 |                   4 | 4,3,2,1         |
|  7 |                   5 | 5,3,2,1         |
|  8 |                   6 | 6,4,3,2,1       |
|  9 |                   4 | 4,3,2,1         |
| 10 |                   5 | 5,3,2,1         |
| 11 |                   6 | 6,4,3,2,1       |
| 12 |                   7 | 7,5,3,2,1       |
| 13 |                   7 | 7,5,3,2,1       |
| 14 |                   8 | 8,6,4,3,2,1     |
| 15 |                   9 | 9,4,3,2,1       |
| 16 |                  10 | 10,5,3,2,1      |
| 17 |                   5 | 5,3,2,1         |
| 18 |                   6 | 6,4,3,2,1       |
| 19 |                   7 | 7,5,3,2,1       |
| 20 |                   8 | 8,6,4,3,2,1     |
| 21 |                   8 | 8,6,4,3,2,1     |
| 22 |                   9 | 9,4,3,2,1       |
| 23 |                  10 | 10,5,3,2,1      |
| 24 |                  11 | 11,6,4,3,2,1    |
| 25 |                   9 | 9,4,3,2,1       |
| 26 |                  10 | 10,5,3,2,1      |
| 27 |                  11 | 11,6,4,3,2,1    |
| 28 |                  12 | 12,7,5,3,2,1    |
| 29 |                  12 | 12,7,5,3,2,1    |
| 30 |                  13 | 13,7,5,3,2,1    |
| 31 |                  14 | 14,8,6,4,3,2,1  |
| 32 |                  15 | 15,9,4,3,2,1    |
+----+---------------------+-----------------+
32 rows in set (0.02 sec)

গল্পটির মোরাল: পুনরাবৃত্ত তথ্য উপাত্ত পুনরুদ্ধার মাইএসকিউএল এ অবশ্যই স্ক্রিপ্ট করা উচিত

আপডেট করুন ২০১০-১০-২৪ ১:17:১। ইডিটি

এখানে getAncestry এর বিপরীত। আমি এটিকে getFamilyTree বলি।

এখানে আলগোরিদিম:

  • কাতারে দেওয়া আইডি রাখুন
  • লুপ
    • সামনের_দিকের দিকে অনুসন্ধান করুন
    • যাদের পিতামাত_আইডি = সামনের_আইডিতে সারিবদ্ধ সমস্ত আইডির পুনরুদ্ধার করুন
    • রেওয়াজ_লিস্টে (আরভি) কুই_চিল্ডার যুক্ত করুন
    • সারিবদ্ধ কিউ_চিল্ডেন
    • ক্রু এবং সারি_সমাজ খালি না হওয়া পর্যন্ত পুনরাবৃত্তি করুন

আমি আমার কলেজের ডেটা স্ট্রাকচার এবং অ্যালগরিদম ক্লাস থেকে বিশ্বাস করি, এটিকে প্রাক অর্ডার / উপসর্গ গাছের ট্র্যাভারসাল জাতীয় কিছু বলা হয়।

কোডটি এখানে:

DELIMITER $$

DROP FUNCTION IF EXISTS `junk`.`GetFamilyTree` $$
CREATE FUNCTION `junk`.`GetFamilyTree` (GivenID INT) RETURNS varchar(1024) CHARSET latin1
DETERMINISTIC
BEGIN

    DECLARE rv,q,queue,queue_children VARCHAR(1024);
    DECLARE queue_length,front_id,pos INT;

    SET rv = '';
    SET queue = GivenID;
    SET queue_length = 1;

    WHILE queue_length > 0 DO
        SET front_id = FORMAT(queue,0);
        IF queue_length = 1 THEN
            SET queue = '';
        ELSE
            SET pos = LOCATE(',',queue) + 1;
            SET q = SUBSTR(queue,pos);
            SET queue = q;
        END IF;
        SET queue_length = queue_length - 1;

        SELECT IFNULL(qc,'') INTO queue_children
        FROM (SELECT GROUP_CONCAT(id) qc
        FROM pctable WHERE parent_id = front_id) A;

        IF LENGTH(queue_children) = 0 THEN
            IF LENGTH(queue) = 0 THEN
                SET queue_length = 0;
            END IF;
        ELSE
            IF LENGTH(rv) = 0 THEN
                SET rv = queue_children;
            ELSE
                SET rv = CONCAT(rv,',',queue_children);
            END IF;
            IF LENGTH(queue) = 0 THEN
                SET queue = queue_children;
            ELSE
                SET queue = CONCAT(queue,',',queue_children);
            END IF;
            SET queue_length = LENGTH(queue) - LENGTH(REPLACE(queue,',','')) + 1;
        END IF;
    END WHILE;

    RETURN rv;

END $$

এখানে প্রতিটি সারি যা উত্পাদন করে তা এখানে

mysql> SELECT id,parent_id,GetParentIDByID(id),GetAncestry(id),GetFamilyTree(id) FROM pctable;
+----+-----------+---------------------+-----------------+--------------------------------------------------------------------------------------+
| id | parent_id | GetParentIDByID(id) | GetAncestry(id) | GetFamilyTree(id)                                                                    |
+----+-----------+---------------------+-----------------+--------------------------------------------------------------------------------------+
|  1 |         0 |                   0 |                 | 2,3,4,5,6,9,7,10,17,8,11,18,15,22,25,12,13,19,16,23,26,14,20,21,24,27,32,28,29,30,31 |
|  2 |         1 |                   1 | 1               | 3,4,5,6,9,7,10,17,8,11,18,15,22,25,12,13,19,16,23,26,14,20,21,24,27,32,28,29,30,31   |
|  3 |         2 |                   2 | 2,1             | 4,5,6,9,7,10,17,8,11,18,15,22,25,12,13,19,16,23,26,14,20,21,24,27,32,28,29,30,31     |
|  4 |         3 |                   3 | 3,2,1           | 6,9,8,11,18,15,22,25,14,20,21,24,27,32,31                                            |
|  5 |         3 |                   3 | 3,2,1           | 7,10,17,12,13,19,16,23,26,28,29,30                                                   |
|  6 |         4 |                   4 | 4,3,2,1         | 8,11,18,14,20,21,24,27,31                                                            |
|  7 |         5 |                   5 | 5,3,2,1         | 12,13,19,28,29,30                                                                    |
|  8 |         6 |                   6 | 6,4,3,2,1       | 14,20,21,31                                                                          |
|  9 |         4 |                   4 | 4,3,2,1         | 15,22,25,32                                                                          |
| 10 |         5 |                   5 | 5,3,2,1         | 16,23,26                                                                             |
| 11 |         6 |                   6 | 6,4,3,2,1       | 24,27                                                                                |
| 12 |         7 |                   7 | 7,5,3,2,1       | 28,29                                                                                |
| 13 |         7 |                   7 | 7,5,3,2,1       | 30                                                                                   |
| 14 |         8 |                   8 | 8,6,4,3,2,1     | 31                                                                                   |
| 15 |         9 |                   9 | 9,4,3,2,1       | 32                                                                                   |
| 16 |        10 |                  10 | 10,5,3,2,1      |                                                                                      |
| 17 |         5 |                   5 | 5,3,2,1         |                                                                                      |
| 18 |         6 |                   6 | 6,4,3,2,1       |                                                                                      |
| 19 |         7 |                   7 | 7,5,3,2,1       |                                                                                      |
| 20 |         8 |                   8 | 8,6,4,3,2,1     |                                                                                      |
| 21 |         8 |                   8 | 8,6,4,3,2,1     |                                                                                      |
| 22 |         9 |                   9 | 9,4,3,2,1       |                                                                                      |
| 23 |        10 |                  10 | 10,5,3,2,1      |                                                                                      |
| 24 |        11 |                  11 | 11,6,4,3,2,1    |                                                                                      |
| 25 |         9 |                   9 | 9,4,3,2,1       |                                                                                      |
| 26 |        10 |                  10 | 10,5,3,2,1      |                                                                                      |
| 27 |        11 |                  11 | 11,6,4,3,2,1    |                                                                                      |
| 28 |        12 |                  12 | 12,7,5,3,2,1    |                                                                                      |
| 29 |        12 |                  12 | 12,7,5,3,2,1    |                                                                                      |
| 30 |        13 |                  13 | 13,7,5,3,2,1    |                                                                                      |
| 31 |        14 |                  14 | 14,8,6,4,3,2,1  |                                                                                      |
| 32 |        15 |                  15 | 15,9,4,3,2,1    |                                                                                      |
+----+-----------+---------------------+-----------------+--------------------------------------------------------------------------------------+
32 rows in set (0.04 sec)

এই অ্যালগরিদম পরিষ্কারভাবে কাজ করে তবে কোনও চক্রীয় পথ নেই provided যদি কোনও চক্রীয় পথ থাকে তবে আপনাকে টেবিলে একটি 'পরিদর্শন করা' কলাম যুক্ত করতে হবে।

একবার আপনি পরিদর্শন করা কলাম যুক্ত করলে, এখানে চক্রীয় সম্পর্কের ব্লক করা অ্যালগরিদমটি রয়েছে:

  • কাতারে দেওয়া আইডি রাখুন
  • সমস্ত 0 দিয়ে পরিদর্শন করা চিহ্নিত করুন
  • লুপ
    • সামনের_দিকের দিকে অনুসন্ধান করুন
    • যাদের পিতামাত_আইডি = সামনের_আইড এবং পরিদর্শন করা হয়েছে = 0 এ সমস্ত আইডিকে পুনরুদ্ধার করুন
    • সমস্ত ক্যু_চিল্ডারকে কেবল দেখা = 1 দিয়ে পুনরুদ্ধার করে চিহ্নিত করুন
    • রেওয়াজ_লিস্টে (আরভি) কুই_চিল্ডার যুক্ত করুন
    • সারিবদ্ধ কিউ_চিল্ডেন
    • ক্রু এবং সারি_সমাজ খালি না হওয়া পর্যন্ত পুনরাবৃত্তি করুন

আপডেট করা হয়েছে 2011-10-24 17:37 ইডিটি

আমি একটি নতুন টেবিল তৈরি করেছি যা পর্যবেক্ষণ বলে। আমি প্যাকটেবলের পরিবর্তে পর্যবেক্ষণগুলি ব্যবহার করার জন্য সঞ্চিত পদ্ধতি পরিবর্তন করেছি। আপনার আউটপুট এখানে:

mysql> CREATE TABLE observations LIKE pctable;
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO observations VALUES (1,3), (2,5), (3,0), (4,10),(5,0),(6,1),(7,5),(8,10),(9,10),(10,3);
Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM observations;
+----+-----------+
| id | parent_id |
+----+-----------+
|  1 |         3 |
|  2 |         5 |
|  3 |         0 |
|  4 |        10 |
|  5 |         0 |
|  6 |         1 |
|  7 |         5 |
|  8 |        10 |
|  9 |        10 |
| 10 |         3 |
+----+-----------+
10 rows in set (0.00 sec)

mysql> SELECT id,parent_id,GetParentIDByID(id),GetAncestry(id),GetFamilyTree(id) FROM observations;
+----+-----------+---------------------+-----------------+-------------------+
| id | parent_id | GetParentIDByID(id) | GetAncestry(id) | GetFamilyTree(id) |
+----+-----------+---------------------+-----------------+-------------------+
|  1 |         3 |                   3 |                 | 6                 |
|  2 |         5 |                   5 | 5               |                   |
|  3 |         0 |                   0 |                 | 1,10,6,4,8,9      |
|  4 |        10 |                  10 | 10,3            |                   |
|  5 |         0 |                   0 |                 | 2,7               |
|  6 |         1 |                   1 | 1               |                   |
|  7 |         5 |                   5 | 5               |                   |
|  8 |        10 |                  10 | 10,3            |                   |
|  9 |        10 |                  10 | 10,3            |                   |
| 10 |         3 |                   3 | 3               | 4,8,9             |
+----+-----------+---------------------+-----------------+-------------------+
10 rows in set (0.01 sec)

আপডেট 2011-10-24 18:22 ইডিটি

আমি getAncestry এর জন্য কোডটি পরিবর্তন করেছি। WHILE ch > 1এটা হওয়া উচিত ছিলWHILE ch > 0

mysql> SELECT id,parent_id,GetParentIDByID(id),GetAncestry(id),GetFamilyTree(id) FROM observations;
+----+-----------+---------------------+-----------------+-------------------+
| id | parent_id | GetParentIDByID(id) | GetAncestry(id) | GetFamilyTree(id) |
+----+-----------+---------------------+-----------------+-------------------+
|  1 |         3 |                   3 | 3               | 6                 |
|  2 |         5 |                   5 | 5               |                   |
|  3 |         0 |                   0 |                 | 1,10,6,4,8,9      |
|  4 |        10 |                  10 | 10,3            |                   |
|  5 |         0 |                   0 |                 | 2,7               |
|  6 |         1 |                   1 | 1,3             |                   |
|  7 |         5 |                   5 | 5               |                   |
|  8 |        10 |                  10 | 10,3            |                   |
|  9 |        10 |                  10 | 10,3            |                   |
| 10 |         3 |                   3 | 3               | 4,8,9             |
+----+-----------+---------------------+-----------------+-------------------+
10 rows in set (0.01 sec)

এটি এখন চেষ্টা করুন !!!


গেটপ্যারেন্টআইবিআইআইডি (আইডি) ফাংশনটি সিলেক্টে ভাল কাজ করছে তবে গেটঅ্যানস্ট্রি (আইডি) সাড়া দিচ্ছে না। আইডি নির্বাচন করুন, ব্যবহারকারীগণের কাছ থেকে গেটপ্যারেন্টআইডি (আইডি); ব্যবহারকারীর সূক্ষ্ম নির্বাচন আইডি, গেটঅ্যানস্ট্রি (আইডি) কাজ করে; সাড়া দিচ্ছে না ... কেবল
পিএইচপিএমইডমিনে

@ রোল্যান্ডোমাইএসকিউএলডিবিএ গেটফ্যামিলি ট্রি ভাল কাজ করে! তবে, বড় গাছের জন্য এটি চক্রাকার করে তোলে। আপনি দয়া করে পরিদর্শিত অংশের জন্য ডিবি ফাংশনটি পরিবর্তন করতে পারেন
নাদেশ্বরান

কেউ কি চক্রীয় পথ প্রয়োগ করে?
عثمان غني

গেটফ্যামিলি ট্রি তে?
عثمان غني

28

নির্দিষ্ট নোডের সমস্ত পিতামাতাকে পাওয়া:

WITH RECURSIVE tree AS ( 
   SELECT id, 
          name, 
          parent_id,
          1 as level 
   FROM the_table
   WHERE name = 'foo'

   UNION ALL 

   SELECT p.id,
          p.name,
          p.parent_id, 
          t.level + 1
   FROM the_table p
     JOIN tree t ON t.parent_id = p.id
)
SELECT *
FROM tree

রুট নোড পেতে, আপনি উদাহরণস্বরূপ ORDER BY levelএবং প্রথম সারিতে নিতে পারেন

একটি নির্দিষ্ট নোডের সমস্ত শিশু পাওয়া:

WITH RECURSIVE tree AS ( 
   SELECT id, 
          name, 
          parent_id,
          1 as level 
   FROM the_table
   WHERE name = 'foo'

   UNION ALL 

   SELECT p.id,
          p.name,
          p.parent_id, 
          t.level + 1
   FROM your_table p
     JOIN tree t ON t.id = p.parent_id
)
SELECT *
FROM tree

(বিবৃতিটির পুনরাবৃত্ত অংশে যোগদানের জন্য অদলবদল শর্তটি নোট করুন)

আমার জানার জন্য নিম্নলিখিত ডিবিএমএস পুনরাবৃত্ত সিটিই সমর্থন করে:

  • ফায়ারবার্ডএসকিউএল ২.১ (এগুলি বাস্তবায়নের জন্য প্রথম ওপেনসোর্স ডিবিএমএস)
  • পোস্টগ্রিএসকিউএল 8.4
  • ডিবি 2 (কোন সঠিক সংস্করণটি নিশ্চিত নয়)
  • ওরাকল (১১.২ থেকে)
  • এসকিউএল সার্ভার 2005 এবং তারপরে
  • Teradata
  • ও H2
  • সাইবাস (কোন সঠিক সংস্করণটি জানেন না)

সম্পাদন করা

আপনার নমুনা তথ্যের উপর ভিত্তি করে, নিম্নলিখিতটি অতিরিক্ত কলাম হিসাবে প্রতিটি নোডের সম্পূর্ণ পথ সহ টেবিল থেকে সমস্ত সাবট্রিকে পুনরুদ্ধার করবে:

with recursive obs_tree as (
   select id, parent_id, '/'||cast(id as varchar) as tree
   from observations
   where parent_id is null

   union all 

   select t.id, t.parent_id, p.tree||'/'||cast(t.id as varchar)
   from observations t
      join obs_tree p on t.parent_id = p.id
)
select id, parent_id, tree
from obs_tree
order by tree

আউটপুটটি এই হবে:

আইডি | প্যারেন্ট_আইডি | গাছ
---- + + ----------- + + ---------
  3 | | / 3
  1 | 3 | / 3/1
  6 | 1 | / 3/1/6
 10 | 3 | / 3/10
  4 | 10 | / 3/10/4
  8 | 10 | / 3/10/8
  9 | 10 | / 3/10/9
  5 | | / 5
  2 | 5 | / 5/2
  7 | 5 | / 5/7

এটি আমার কাছ থেকে একটি +1 পান কারণ আপনার কোডটি অনেক বেশি পরিস্কার, স্বজ্ঞাত এবং সংক্ষিপ্ত। এদিকে ঝাঁপিয়ে পড়ার মতো অনেকগুলি হুপ রয়েছে। মাইএসকিউএল পুনরাবৃত্তির তথ্য পুনরুদ্ধারের জন্য আরও মার্জিত প্রক্রিয়া সরবরাহ করেনি এটি হাহাকার লজ্জাজনক is
রোল্যান্ডোমাইএসকিউএলডিবিএ

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

8

রোল্যান্ডোর উত্তরে গেটফ্যামিলি ট্রি ফাংশনটি কার্যকর হয় না যখন প্রদত্ত আইডিটি 4 টিরও বেশি পূর্ণসংখ্যা হয়, কারণ ফর্ম্যাট মাইএসকিউএল ফাংশনটিতে হাজার বিভাজককে কমা যুক্ত করা হয়। আমি নীচের মতো বড় পূর্ণসংখ্যার আইডির সাথে কাজ করতে স্টোরেজ ফাংশন গেটফ্যামিলিটিরি পরিবর্তন করেছি:

WHILE queue_length > 0 DO
    IF queue_length = 1 THEN
    SET front_id = queue;
        SET queue = '';
    ELSE
    SET front_id = SUBSTR(queue,1,LOCATE(',',queue)-1);
        SET pos = LOCATE(',',queue) + 1;
        SET q = SUBSTR(queue,pos);
        SET queue = q;
    END IF;

সামনের_আইডি সংজ্ঞায়িত যদি অন্য লুপ।


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