মাইএসকিউএল: বৃক্ষ-শ্রেণিবদ্ধ কোয়েরি


20

মাইএসকিউএলে একটি গাছ ছাড়া সাব-ট্রি UB

আমার জুমলা ইন Database COMPANY, আমি একটি আছে Table: Employeeঅন্যান্য কর্মচারীর মনিব রিকার্সিভ সমিতি সঙ্গে, একজন কর্মী হতে পারে। A self relationship of kind (SuperVisor (1)- SuperVisee (∞) )

সারণী তৈরি করতে প্রশ্ন:

CREATE TABLE IF NOT EXISTS `Employee` (
  `SSN` varchar(64) NOT NULL,
  `Name` varchar(64) DEFAULT NULL,
  `Designation` varchar(128) NOT NULL,
  `MSSN` varchar(64) NOT NULL, 
  PRIMARY KEY (`SSN`),
  CONSTRAINT `FK_Manager_Employee`  
              FOREIGN KEY (`MSSN`) REFERENCES Employee(SSN)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

আমি টিপলস (কোয়েরি) এর একটি সেট inোকালাম:

INSERT INTO Employee VALUES 
 ("1", "A", "OWNER",  "1"),  

 ("2", "B", "BOSS",   "1"), # Employees under OWNER 
 ("3", "F", "BOSS",   "1"),

 ("4", "C", "BOSS",   "2"), # Employees under B
 ("5", "H", "BOSS",   "2"), 
 ("6", "L", "WORKER", "2"), 
 ("7", "I", "BOSS",   "2"), 
 # Remaining Leaf nodes   
 ("8", "K", "WORKER", "3"), # Employee under F     

 ("9", "J", "WORKER", "7"), # Employee under I     

 ("10","G", "WORKER", "5"), # Employee under H

 ("11","D", "WORKER", "4"), # Employee under C
 ("12","E", "WORKER", "4")  

Rোকানো সারিগুলিতে নিম্নলিখিত গাছ-হায়ারার্কিকাল-সম্পর্ক রয়েছে :

         A     <---ROOT-OWNER
        /|\             
       / A \        
      B     F 
    //| \    \          
   // |  \    K     
  / | |   \                     
 I  L H    C        
/     |   / \ 
J     G  D   E

সম্পর্ক খোঁজার জন্য আমি একটি ক্যোয়ারী লিখেছি:

SELECT  SUPERVISOR.name AS SuperVisor, 
        GROUP_CONCAT(SUPERVISEE.name  ORDER BY SUPERVISEE.name ) AS SuperVisee, 
        COUNT(*)  
FROM Employee AS SUPERVISOR 
  INNER JOIN Employee SUPERVISEE ON  SUPERVISOR.SSN = SUPERVISEE.MSSN 
GROUP BY SuperVisor;

এবং আউটপুট হল:

+------------+------------+----------+
| SuperVisor | SuperVisee | COUNT(*) |
+------------+------------+----------+
| A          | A,B,F      |        3 |
| B          | C,H,I,L    |        4 |
| C          | D,E        |        2 |
| F          | K          |        1 |
| H          | G          |        1 |
| I          | J          |        1 |
+------------+------------+----------+
6 rows in set (0.00 sec)

[ প্রশ্ন ]
সম্পূর্ণ শ্রেণিবদ্ধ গাছের পরিবর্তে, আমার SUB-TREEএকটি বিন্দু (সিলেক্টিক) থেকে একটি প্রয়োজন যেমন:
ইনপুট আর্গুমেন্ট যদি হয় Bতবে আউটপুট নীচের মতো হওয়া উচিত ...

+------------+------------+----------+
| SuperVisor | SuperVisee | COUNT(*) |
+------------+------------+----------+
| B          | C,H,I,L    |        4 |
| C          | D,E        |        2 |
| H          | G          |        1 |
| I          | J          |        1 |
+------------+------------+----------+   

এই আমাকে সাহায্য করুন। যদি জিজ্ঞাসা না হয় তবে একটি সঞ্চিত পদ্ধতি কার্যকর হতে পারে।
আমি চেষ্টা করেছিলাম, কিন্তু সমস্ত প্রচেষ্টা অকেজো ছিল!



আমি আরও সহজেই এই প্রশ্নটি অন্বেষণে সম্প্রদায়টির জন্য একটি পরীক্ষার কাঠামো সরবরাহ করেছি।
মেল্লামোকব

@ ব্লুয়েফেট হ্যাঁ, একবার উত্তর পেলে আমি এই দু'জনের একটি মুছে ফেলব।
গ্রিজেশ চৌহান

1
@ গ্রিজেশচৌহান আমাকে আপনার জিজ্ঞাসা করতে দিন: আপনার নিজের দৃশ্যমান তরঙ্গগুলি তৈরি করা ভাল কোনটি? সমুদ্রের মধ্যে নুড়ি নিক্ষেপ করতে, বা একটি ছোট পুকুরে পাথর নিক্ষেপ করতে? বিশেষজ্ঞদের কাছে সরাসরি যাওয়া প্রায় অবশ্যই আপনাকে সর্বোত্তম উত্তর দিতে চলেছে, এবং এই ধরণের প্রশ্নটি এত গুরুত্বপূর্ণ (উন্নত ডাটাবেসের বিষয়সমূহ) যা আমরা এটি নেটওয়ার্কে এটির নিজস্ব সাইট দিয়েছি। তবে আপনি কোথায় চান তা জিজ্ঞাসা করতে আমি বাধা দেব না, এটিই আপনার অগ্রগামী। আমার প্রগ্রেটিভটি হ'ল যদি আমি মনে করি যে এটি যেখানে রয়েছে তখনই এটি অন্য কোনও সাইটে নিয়ে যাওয়া উচিত। : ডি আমরা উভয় ব্যবহার নেটওয়ার্কের হিসাবে আমরা এই ক্ষেত্রে হইয়া দেখুন: D:
jcolebrand

1
@ জকোলেব্রান্ড: আসলে এটি আমার দোষ ছিল। আমি আরও ভাল, দ্রুত এবং অনেক প্রতিক্রিয়া পেতে একাধিক পক্ষের প্রশ্ন পোস্ট করতে ব্যবহার করি। It my experience আমি সর্বদা বিশেষজ্ঞ পক্ষের কাছ থেকে আরও ভাল উত্তর পেয়েছি । এবং আমি মনে করি যে ডেটাবেস প্রশাসকদের কাছে প্রশ্ন সরিয়ে নেওয়া ভাল সিদ্ধান্ত ছিল। সব ক্ষেত্রেই, আমি স্ট্যাকওভারফ্লো এবং এখানে সক্রিয় লোকদের জন্য অত্যন্ত কৃতজ্ঞ। আমি সত্যিই অনেক সমস্যার সমাধান পেয়েছি যা নিজেকে বা অন্য কোনও ওয়েব খুঁজে পাওয়া খুব শক্ত ছিল।
গ্রিজেশ চৌহান

উত্তর:


5

আমি ইতিমধ্যে সঞ্চিত পদ্ধতি ব্যবহার করে এই প্রকৃতির কিছুটিকে সম্বোধন করেছি: একটি শ্রেণিবিন্যাসের ক্ষেত্রের সর্বোচ্চ স্তর সন্ধান করুন: সিটিই ছাড়াই বনাম (অক্টোবর 24, 2011)

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

আপডেট 2012-12-11 12:11 ইডিটি

আমি আমার পোস্ট থেকে আমার কোডটির দিকে ফিরে তাকালাম । আমি আপনার জন্য সঞ্চিত ফাংশন লিখেছিলাম:

DELIMITER $$

DROP FUNCTION IF EXISTS `cte_test`.`GetFamilyTree` $$
CREATE FUNCTION `cte_test`.`GetFamilyTree`(GivenName varchar(64))
RETURNS varchar(1024) CHARSET latin1
DETERMINISTIC
BEGIN

    DECLARE rv,q,queue,queue_children,queue_names VARCHAR(1024);
    DECLARE queue_length,pos INT;
    DECLARE GivenSSN,front_ssn VARCHAR(64);

    SET rv = '';

    SELECT SSN INTO GivenSSN
    FROM Employee
    WHERE name = GivenName
    AND Designation <> 'OWNER';
    IF ISNULL(GivenSSN) THEN
        RETURN ev;
    END IF;

    SET queue = GivenSSN;
    SET queue_length = 1;

    WHILE queue_length > 0 DO
        IF queue_length = 1 THEN
            SET front_ssn = queue;
            SET queue = '';
        ELSE
            SET pos = LOCATE(',',queue);
            SET front_ssn = LEFT(queue,pos - 1);
            SET q = SUBSTR(queue,pos + 1);
            SET queue = q;
        END IF;
        SET queue_length = queue_length - 1;
        SELECT IFNULL(qc,'') INTO queue_children
        FROM
        (
            SELECT GROUP_CONCAT(SSN) qc FROM Employee
            WHERE MSSN = front_ssn AND Designation <> 'OWNER'
        ) A;
        SELECT IFNULL(qc,'') INTO queue_names
        FROM
        (
            SELECT GROUP_CONCAT(name) qc FROM Employee
            WHERE MSSN = front_ssn AND Designation <> 'OWNER'
        ) 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_names;
            ELSE
                SET rv = CONCAT(rv,',',queue_names);
            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 name,GetFamilyTree(name) FamilyTree
    -> FROM Employee WHERE Designation <> 'OWNER';
+------+-----------------------+
| name | FamilyTree            |
+------+-----------------------+
| A    | B,F,C,H,L,I,K,D,E,G,J |
| G    |                       |
| D    |                       |
| E    |                       |
| B    | C,H,L,I,D,E,G,J       |
| F    | K                     |
| C    | D,E                   |
| H    | G                     |
| L    |                       |
| I    | J                     |
| K    |                       |
| J    |                       |
+------+-----------------------+
12 rows in set (0.36 sec)

mysql>

কেবল একটি ধরা আছে। আমি মালিকের জন্য একটি অতিরিক্ত সারি যুক্ত করেছি

  • মালিকের এসএসএন 0 রয়েছে
  • মালিক এমএসএসএন 0 এর নিজস্ব মালিক bo

এখানে তথ্য আছে

mysql> select * from Employee;
+-----+------+-------------+------+
| SSN | Name | Designation | MSSN |
+-----+------+-------------+------+
| 0   | A    | OWNER       | 0    |
| 1   | A    | BOSS        | 0    |
| 10  | G    | WORKER      | 5    |
| 11  | D    | WORKER      | 4    |
| 12  | E    | WORKER      | 4    |
| 2   | B    | BOSS        | 1    |
| 3   | F    | BOSS        | 1    |
| 4   | C    | BOSS        | 2    |
| 5   | H    | BOSS        | 2    |
| 6   | L    | WORKER      | 2    |
| 7   | I    | BOSS        | 2    |
| 8   | K    | WORKER      | 3    |
| 9   | J    | WORKER      | 7    |
+-----+------+-------------+------+
13 rows in set (0.00 sec)

mysql>

আইডিয়া বুঝেছি!
গ্রিজেশ চৌহান

আমি এর Aমতো সমস্ত বংশদ্ভুত পেতে কীভাবে মানিয়ে নিতে পারিA A/B A/B/C A/B/C/D A/B/C/E A/B/H A/B/H/G A/B/I A/B/I/J A/B/L A/F A/F/K
স্মিথ

এটি মাল্টিনোডগুলিও পরিচালনা করে? যেহেতু এটি আমার ডাটাবেসে ঝুলছে যেখানে পিতামাতার একাধিক নোড পাওয়া গেছে
عثمان غني

3

আপনি যা ব্যবহার করছেন তাকে অ্যাডজেসেন্সি তালিকা মডেল বলে । এটির অনেক সীমাবদ্ধতা রয়েছে। আপনি নির্দিষ্ট জায়গায় কোনও নোড মুছতে / toোকাতে চাইলে সমস্যা হবে। এটি আরও ভাল আপনি নেস্টেড সেট মডেল ব্যবহার করুন

এর বিশদ ব্যাখ্যা রয়েছে । দুর্ভাগ্যক্রমে mysql.com এ নিবন্ধটির আর অস্তিত্ব নেই।


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

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