[SQL] 어떻게 재귀 아이들의 모든 ID를 찾는 방법은?
SQL어떻게 재귀 아이들의 모든 ID를 찾는 방법은?
난 단지 MySQL을 가진 나무에 아이의 모든 ID를 좀하고 싶습니다.
나는이 같은 테이블이 있습니다 :
ID parent_id name
1 0 cat1
2 1 subcat1
3 2 sub-subcat1
4 2 sub-subcat2
5 0 cat2
지금은 재귀 적으로 CAT1 (2,3,4)에 대한 모든 자식 ID를 얻기 위해 노력하고있어. 그것을 달성하는 방법을 방법이 있습니까?
해결법
-
==============================
1.인접 목록 및 중첩 된 목록 :이 작업을 수행하는 두 가지 방법이있다. MySQL의 계층 적 데이터 관리를 살펴 보자.
인접 목록 및 중첩 된 목록 :이 작업을 수행하는 두 가지 방법이있다. MySQL의 계층 적 데이터 관리를 살펴 보자.
당신이해야하는 것은 인접 목록입니다. 아니 재귀 적으로 하나의 SQL 문으로 모든 자손을 잡는 방법이 없습니다. 가능하다면, 단지 그들 모두를 잡아 모든 코드를 매핑합니다.
중첩 된 세트는 당신이 원하는 것을 할 수 있지만 기록을 삽입하는 비용이 높기 때문에이를 방지하기 위해 경향이 오류가 발생하기 쉬운입니다.
-
==============================
2.다음은 간단한 단일 쿼리 MySQL의-솔루션입니다 :
다음은 간단한 단일 쿼리 MySQL의-솔루션입니다 :
SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM ( SELECT @Ids := ( SELECT GROUP_CONCAT(`ID` SEPARATOR ',') FROM `table_name` WHERE FIND_IN_SET(`parent_id`, @Ids) ) Level FROM `table_name` JOIN (SELECT @Ids := <id>) temp1 ) temp2
부모 요소의 ID와 그냥 대신
. 이 ID를 가진 요소의 모든 자손의 ID가 문자열을 반환 = <이드>에 의해 분리된다. 오히려 여러 행이 각 행에 하나의 자손으로, 반환했을 경우, 다음과 같이 사용할 수 있습니다 :
SELECT * FROM `table_name` WHERE FIND_IN_SET(`ID`, ( SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM ( SELECT @Ids := ( SELECT GROUP_CONCAT(`ID` SEPARATOR ',') FROM `table_name` WHERE FIND_IN_SET(`parent_id`, @Ids) ) Level FROM `table_name` JOIN (SELECT @Ids := <id>) temp1 ) temp2 ))
루트 / 부모 요소 포함
영업 이익은 위에서 대답하는 요소의 아이들을 위해 물었다. 어떤 경우에는 결과의 루트 / 부모 요소를 포함하는 유용 할 수 있습니다. 여기 내 제안 된 솔루션은 다음과 같습니다 :
ID의 문자열을 쉼표로 구분 :
SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM ( SELECT <id> Level UNION SELECT @Ids := ( SELECT GROUP_CONCAT(`ID` SEPARATOR ',') FROM `table_name` WHERE FIND_IN_SET(`parent_id`, @Ids) ) Level FROM `table_name` JOIN (SELECT @Ids := <id>) temp1 ) temp2
여러 행 :
SELECT * FROM `table_name` WHERE `ID` = <id> OR FIND_IN_SET(`ID`, ( SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM ( SELECT @Ids := ( SELECT GROUP_CONCAT(`ID` SEPARATOR ',') FROM `table_name` WHERE FIND_IN_SET(`parent_id`, @Ids) ) Level FROM `table_name` JOIN (SELECT @Ids := <id>) temp1 ) temp2 ))
-
==============================
3.즉 당신을위한 옵션이 있다면 당신은 아마, 저장 프로 시저와 함께 할 수 있습니다.
즉 당신을위한 옵션이 있다면 당신은 아마, 저장 프로 시저와 함께 할 수 있습니다.
그렇지 않으면 당신은 하나의 SQL 문으로 할 수 없습니다.
이상적으로 당신은 당신의 프로그램에서 트리를 걸어 재귀 호출을한다
-
==============================
4.
DROP TABLE IF EXISTS `parent_child`; CREATE TABLE `parent_child` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `parent_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1; insert into `parent_child`(`id`,`name`,`parent_id`) values (1,'cat1',0),(2,'subcat1',1), (3,'sub-subcat1',2),(4,'sub-subcat2',2), (5,'cat2',0);
DELIMITER $$ USE `yourdatabase`$$ DROP FUNCTION IF EXISTS `GetAllNode1`$$ CREATE DEFINER=`root`@`localhost` FUNCTION `GetAllNode1`(GivenID INT) RETURNS TEXT CHARSET latin1 DETERMINISTIC BEGIN DECLARE rv,q,queue,queue_children TEXT; DECLARE queue_length,front_id,pos INT; SET rv = ''; SET queue = GivenID; SET queue_length = 1; WHILE queue_length > 0 DO SET front_id = queue; IF queue_length = 1 THEN SET queue = ''; ELSE SET pos = LOCATE(',',queue) + 1; SET q = SUBSTR(queue,pos); SET queue = q; END IF; SET queue_length = queue_length - 1; SELECT IFNULL(qc,'') INTO queue_children FROM (SELECT GROUP_CONCAT(id) AS qc FROM `parent_child` WHERE `parent_id` = front_id) 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_children; ELSE SET rv = CONCAT(rv,',',queue_children); 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$$ DELIMITER ;
SELECT GetAllNode1(id) FROM parent_child or SELECT GetAllNode1(id) FROM parent_child where id =1 //for specific parent's child element
-
==============================
5.대답은 하나의 MYSQL 문으로 매우 쉽게 기본적 없거나 적어도 아니라고보고하지, 내가 계층 구조 목록을 내 PHP / MySQL의 코드를 게시 할 수 있습니다 ..
대답은 하나의 MYSQL 문으로 매우 쉽게 기본적 없거나 적어도 아니라고보고하지, 내가 계층 구조 목록을 내 PHP / MySQL의 코드를 게시 할 수 있습니다 ..
function createCategorySubArray() { $categories = getSQL("SELECT pos_category_id FROM pos_categories"); for($i=0;$i<sizeof($categories);$i++) { //here we need to find all sub categories $pos_category_id = $categories[$i]['pos_category_id']; $cat_list[$pos_category_id] = recursiveCategory($pos_category_id,array()); } return $cat_list; } function recursiveCategory($pos_category_id, $array) { $return = getSql("SELECT pos_category_id FROM pos_categories WHERE parent = $pos_category_id"); for($i=0;$i<sizeof($return);$i++) { $sub_cat = $return[$i]['pos_category_id']; $array[] = $sub_cat; $array = recursiveCategory($sub_cat, $array); } return $array; }
그런 다음에 의해 호출 $ cat_array createCategorySubArray = ();
나는 이것이 하위 범주에 적용되고있는 제품 카테고리에 따라 프로모션 찾을 필요가있다.
-
==============================
6.귀하의 질문은 약간의 부정확 한 것 같습니다. 왜 당신이 그들을 갖고 싶어 할, 당신은 "트리"를 가지고 무엇을 의미합니까?
귀하의 질문은 약간의 부정확 한 것 같습니다. 왜 당신이 그들을 갖고 싶어 할, 당신은 "트리"를 가지고 무엇을 의미합니까?
당신이있어 표는 트리 (대표하는 관계형 방법)입니다.
당신이 그들을 원하는 경우 쌍을 보유 행 (ID 4, ParentID 0)와 "테이블에서"당신은이 작업을 수행하는 경우 그 엔진 지원을 재귀 SQL의 사용자의 SQL 엔진의 버전이 필요합니다.
내가 특별히 MySQL을 모르는 것이다, 그러나 나의 이해는 한 번 CONNECT BY와 즉 오라클, 같은 구문을 사용하여 재귀 SQL을 구현할 계획이다.
당신은 "재귀 쿼리"또는 "CONNECT BY"로 키워드에 대한 내용의 수동의 표에서 보면, 난 당신이 답을 찾을 수있을 것입니다 상상한다.
(죄송합니다보다 즉시 소비하는 답을 제공 할 수 없다는합니다.)
from https://stackoverflow.com/questions/990529/how-to-find-all-ids-of-children-recursively by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] ( "LIKE"및 "="비교) REGEXP 성능 (0) | 2020.06.29 |
---|---|
[SQL] PHP : 단일 쿼리에서 업데이트 여러 MySQL의 필드 (0) | 2020.06.29 |
[SQL] 하나 개의 배치에서 두 개의 서로 다른 준비된 문 (0) | 2020.06.29 |
[SQL] SQL Server로 변환 MySQL의 스크립트 [마감] (0) | 2020.06.29 |
[SQL] 대신 NULL의 어떻게 SELECT 문 SQL과 결과에 '0'표시합니까? (0) | 2020.06.29 |