यदि आप चाहते हैं कि चाइल्ड आईडी से कम होने वाली पेरेंट आईडी की समस्याओं के बिना एक सेलेक्ट हो सके, तो फंक्शन का उपयोग किया जा सकता है। यह कई बच्चों का भी समर्थन करता है (जैसा कि एक पेड़ को करना चाहिए) और पेड़ के कई सिर हो सकते हैं। यदि डेटा में एक लूप मौजूद है, तो यह भी टूटना सुनिश्चित करता है।
मैं तालिका / स्तंभ नामों को पारित करने में सक्षम होने के लिए गतिशील SQL का उपयोग करना चाहता था, लेकिन MySQL में फ़ंक्शन इसका समर्थन नहीं करते हैं।
DELIMITER $$
CREATE FUNCTION `isSubElement`(pParentId INT, pId INT) RETURNS int(11)
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE isChild,curId,curParent,lastParent int;
SET isChild = 0;
SET curId = pId;
SET curParent = -1;
SET lastParent = -2;
WHILE lastParent <> curParent AND curParent <> 0 AND curId <> -1 AND curParent <> pId AND isChild = 0 DO
SET lastParent = curParent;
SELECT ParentId from `test` where id=curId limit 1 into curParent;
IF curParent = pParentId THEN
SET isChild = 1;
END IF;
SET curId = curParent;
END WHILE;
RETURN isChild;
END$$
यहां, तालिका test
को वास्तविक तालिका नाम में संशोधित किया जाना है और आपके वास्तविक नामों के लिए कॉलम (ParentId, Id) को समायोजित करना पड़ सकता है।
उपयोग:
SET @wantedSubTreeId = 3;
SELECT * FROM test WHERE isSubElement(@wantedSubTreeId,id) = 1 OR ID = @wantedSubTreeId;
परिणाम :
3 7 k
5 3 d
9 3 f
1 5 a
परीक्षण के निर्माण के लिए एसक्यूएल:
CREATE TABLE IF NOT EXISTS `test` (
`Id` int(11) NOT NULL,
`ParentId` int(11) DEFAULT NULL,
`Name` varchar(300) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into test (id, parentid, name) values(3,7,'k');
insert into test (id, parentid, name) values(5,3,'d');
insert into test (id, parentid, name) values(9,3,'f');
insert into test (id, parentid, name) values(1,5,'a');
insert into test (id, parentid, name) values(6,2,'o');
insert into test (id, parentid, name) values(2,8,'c');
संपादित करें: यहाँ अपने आप को परीक्षण करने के लिए एक बेला है। इसने मुझे पूर्वनिर्धारित एक का उपयोग करके सीमांकक को बदलने के लिए मजबूर किया, लेकिन यह काम करता है।