यद्यपि आप एक प्रश्न के साथ नहीं कर सकते हैं, आप एक संग्रहीत कार्यविधि के साथ कर सकते हैं... केवल पूर्व-आवश्यकता, आपको अपनी मौजूदा नमूना तालिका में 2 और रिकॉर्ड जोड़ने की आवश्यकता है ताकि यह दर्शाया जा सके कि "C1" और "C2" हैं शीर्ष स्तर... एक रिकॉर्ड जोड़ें जहां "अभिभावक" फ़ील्ड खाली है, और चाइल्ड स्तर "C1" है और दूसरा "C2" के लिए है। यह सबसे शीर्ष अभिभावक स्तर को "तैयार" करेगा। बाद के पदानुक्रम संघ के लिए, अन्यथा आपके पास शीर्ष-स्तरीय पदानुक्रम का कोई प्रारंभिक "आधार" नहीं है। इसके लिए एक "प्राथमिक कुंजी" कॉलम की भी आवश्यकता होती है (जिसे मैंने इस स्क्रिप्ट में "IDMyTable" के रूप में बनाया है जो कि केवल 1-x अनुक्रमिक है, लेकिन यह मान लेगा कि आपके पास उपयोग करने के लिए आपकी टेबल पर एक ऑटो-इन्क्रीमेंट कॉलम है)।पी>
मैंने यह दिखाने के लिए सभी आउटपुट कॉलम शामिल किए हैं कि यह कैसे बनाया गया है, लेकिन इस दिनचर्या का आधार अपेक्षित कॉलम आउटपुट के आधार पर एक टेबल बनाना है, फिर भी पदानुक्रमित प्रतिनिधित्व डाउनस्ट्रीम को बनाए रखने के लिए अतिरिक्त है। यह सुनिश्चित करने के लिए कि जैसे-जैसे परतें गहरी होती जाती हैं, वे सही अभिविन्यास बनाए रखते हैं, मैं "आईडी" कॉलम को जोड़ रहा हूं - आप देखेंगे कि यह अंतिम परिणाम सेट में कैसे काम करता है।
फिर, अंतिम परिणाम सेट में, पदानुक्रम डेटा कितना भी गहरा क्यों न हो, मैं प्री-पैडिंग रिक्त स्थान हूं।
लूप उनके माता-पिता के पिछले परिणाम सेट में पाए जाने के आधार पर कोई भी रिकॉर्ड जोड़ देगा, लेकिन केवल तभी जब आईडी पहले से नहीं जोड़ा गया हो (डुप्लिकेट को रोकें)...
यह देखने के लिए कि कैसे चक्रीय क्रम को लगातार जोड़ा गया था, आप बिना क्रम के अंतिम क्वेरी चला सकते हैं और देख सकते हैं कि प्रत्येक पुनरावृत्ति कैसे योग्य है और पिछले पदानुक्रम स्तर को कैसे लागू किया गया था...
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `GetHierarchy2`()
BEGIN
-- prepare a hierarchy level variable
set @hierlvl := 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
t1.IDMyTable,
t1.Child AS Parent,
@hierlvl as IDHierLevel,
cast( t1.IDMyTable as char(100)) FullHierarchy
from
MyTable t1
where
t1.Parent is null
OR t1.Parent = '';
-- how many rows are we starting with at this tier level
set @lastRowCount := ROW_COUNT();
-- we need to have a "primary key", otherwise our UPDATE
-- statement will nag about an unsafe update command
alter table MyHierarchy add primary key (IDMyTable);
-- NOW, keep cycling through until we get no more records
while @lastRowCount > 0 do
-- NOW, load in all entries found from full-set NOT already processed
insert into MyHierarchy
select
t1.IDMyTable,
t1.Child as Parent,
h1.IDHierLevel +1 as IDHierLevel,
concat_ws( ',', h1.FullHierarchy, t1.IDMyTable ) as FullHierarchy
from
MyTable t1
join MyHierarchy h1
on t1.Parent = h1.Parent
left join
MyHierarchy h2
on t1.IDMyTable = h2.IDMyTable
where
h2.IDMyTable is null;
set @lastRowCount := row_count();
-- now, update the hierarchy level
set @hierLevel := @hierLevel +1;
end while;
-- return the final set now
select
*, concat( lpad( ' ', 1 + (IDHierLevel * 3 ), ' ' ), Parent ) as ShowHierarchy
from MyHierarchy
order by FullHierarchy;
END