CREATE DEFINER = 'root'@'localhost'
PROCEDURE test.GetHierarchyUsers(IN StartKey INT)
BEGIN
-- prepare a hierarchy level variable
SET @hierlevel := 00000;
-- prepare a variable for total rows so we know when no more rows found
SET @lastRowCount := 0;
-- pre-drop temp table
DROP TABLE IF EXISTS MyHierarchy;
-- now, create it as the first level you want...
-- ie: a specific top level of all "no parent" entries
-- or parameterize the function and ask for a specific "ID".
-- add extra column as flag for next set of ID's to load into this.
CREATE TABLE MyHierarchy AS
SELECT U.ID
, U.Parent
, U.`name`
, 00 AS IDHierLevel
, 00 AS AlreadyProcessed
FROM
Users U
WHERE
U.ID = StartKey;
-- how many rows are we starting with at this tier level
-- START the cycle, only IF we found rows...
SET @lastRowCount := FOUND_ROWS();
-- we need to have a "key" for updates to be applied against,
-- otherwise our UPDATE statement will nag about an unsafe update command
CREATE INDEX MyHier_Idx1 ON MyHierarchy (IDHierLevel);
-- NOW, keep cycling through until we get no more records
WHILE @lastRowCount > 0
DO
UPDATE MyHierarchy
SET
AlreadyProcessed = 1
WHERE
IDHierLevel = @hierLevel;
-- NOW, load in all entries found from full-set NOT already processed
INSERT INTO MyHierarchy
SELECT DISTINCT U.ID
, U.Parent
, U.`name`
, @hierLevel + 1 AS IDHierLevel
, 0 AS AlreadyProcessed
FROM
MyHierarchy mh
JOIN Users U
ON mh.Parent = U.ID
WHERE
mh.IDHierLevel = @hierLevel;
-- preserve latest count of records accounted for from above query
-- now, how many acrual rows DID we insert from the select query
SET @lastRowCount := ROW_COUNT();
-- only mark the LOWER level we just joined against as processed,
-- and NOT the new records we just inserted
UPDATE MyHierarchy
SET
AlreadyProcessed = 1
WHERE
IDHierLevel = @hierLevel;
-- now, update the hierarchy level
SET @hierLevel := @hierLevel + 1;
END WHILE;
-- return the final set now
SELECT *
FROM
MyHierarchy;
-- and we can clean-up after the query of data has been selected / returned.
-- drop table if exists MyHierarchy;
END
यह बोझिल लग सकता है, लेकिन इसका उपयोग करने के लिए, यह करें
call GetHierarchyUsers( 5 );
(या जो भी कुंजी आईडी आप यूपी के लिए पदानुक्रमित पेड़ खोजना चाहते हैं)।
आधार उस एक कुंजी से शुरू करना है जिसके साथ आप काम कर रहे हैं। फिर, उपयोगकर्ता तालिका में फिर से शामिल होने के लिए आधार के रूप में इसका उपयोग करें, लेकिन पहली प्रविष्टि की PARENT ID के आधार पर। एक बार मिल जाने के बाद, अगले चक्र पर फिर से उस कुंजी के लिए प्रयास न करने और शामिल होने के लिए अस्थायी तालिका को अपडेट करें। तब तक चलते रहें जब तक कि कोई और "पैरेंट" आईडी कुंजियाँ न मिलें।
यह रिकॉर्ड के पूरे पदानुक्रम को माता-पिता तक वापस कर देगा, चाहे कितना भी गहरा घोंसला क्यों न हो। हालाँकि, यदि आप केवल अंतिम अभिभावक चाहते हैं, तो आप जोड़ी गई फ़ाइल में केवल नवीनतम को वापस करने के लिए @hierlevel चर का उपयोग कर सकते हैं, या ORDER BY और LIMIT 1