解决方案
PosgreSQL、Oracle、MS-SQL……必须WITH RECURSIVE
处理这样的数据结构。它在内部使用一个while循环来获取parent ids
当前行的所有内容(我们需要孩子在这里)
这也可以实现MySQL
,您可以创建stored procedure
并重现相同的行为
假定/使用 DDL
content_has_content
条目为
content_1
content_2
content_3
content_4
我通过id_content
as 2 并获得输出为
content_2
content_3
content_4
以上皆为后代content_2
触发call content_details(2);
以获取传递的所有子行id_content
SQL
###### Stored Routine
DELIMITER //
drop procedure IF EXISTS `content_details`;
CREATE DEFINER=`root`@`localhost` PROCEDURE `content_details`(`_idcontent` INT)
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE temp_content_ids varchar(200);
DECLARE idcontent, idcontent2 integer;
SET temp_content_ids= _idcontent;
SET idcontent = _idcontent;
SET idcontent2 = _idcontent;
WHILE idcontent2 IS NOT NULL DO
SET idcontent = NULL;
SELECT id_subcontent, CONCAT(id_subcontent,',',temp_content_ids) INTO idcontent, temp_content_ids FROM content_has_content WHERE id_content = idcontent2;
SET idcontent2 = idcontent;
END WHILE;
SELECT my_string1 FROM content WHERE FIND_IN_SET( id, temp_content_ids );
END//
我基本上做的是运行 awhile loop
直到我有最后一个child_id
,将它们存储ids
在 acomma separated string format
然后触发查询以获取我刚刚创建id
的所有行var
注意:您的表中可能有无效值,例如行有 a id_subcontent
,它指向它自己的id_content
,这可能导致过程中永无止境loop
,为避免这种情况,您可以使用计数器并限制嵌套说大约 50(或根据您的要求的任何值),raise a exception
如果超过该限制
一些数据可以玩..
###### DLL Statements
CREATE TABLE content
( id_content int,
my_string1 varchar(200));
CREATE TABLE content_has_content
( id_content int,
id_subcontent int);
CREATE TABLE topic_has_content
( id_topic int,
id_content int);
INSERT INTO content VALUES (1, 'content_1'), (2, 'content_2'), (3, 'content_3'), (4, 'content_4');
INSERT INTO content_has_content VALUES (1, 2), (2, 3), (3, 4);
INSERT INTO topic_has_content VALUES (1, 1);
希望这可以帮助..