복붙노트

[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. ==============================

    1.인접 목록 및 중첩 된 목록 :이 작업을 수행하는 두 가지 방법이있다. MySQL의 계층 적 데이터 관리를 살펴 보자.

    인접 목록 및 중첩 된 목록 :이 작업을 수행하는 두 가지 방법이있다. MySQL의 계층 적 데이터 관리를 살펴 보자.

    당신이해야하는 것은 인접 목록입니다. 아니 재귀 적으로 하나의 SQL 문으로 모든 자손을 잡는 방법이 없습니다. 가능하다면, 단지 그들 모두를 잡아 모든 코드를 매핑합니다.

    중첩 된 세트는 당신이 원하는 것을 할 수 있지만 기록을 삽입하는 비용이 높기 때문에이를 방지하기 위해 경향이 오류가 발생하기 쉬운입니다.

  2. ==============================

    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. ==============================

    3.즉 당신을위한 옵션이 있다면 당신은 아마, 저장 프로 시저와 함께 할 수 있습니다.

    즉 당신을위한 옵션이 있다면 당신은 아마, 저장 프로 시저와 함께 할 수 있습니다.

    그렇지 않으면 당신은 하나의 SQL 문으로 할 수 없습니다.

    이상적으로 당신은 당신의 프로그램에서 트리를 걸어 재귀 호출을한다

  4. ==============================

    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. ==============================

    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. ==============================

    6.귀하의 질문은 약간의 부정확 한 것 같습니다. 왜 당신이 그들을 갖고 싶어 할, 당신은 "트리"를 가지고 무엇을 의미합니까?

    귀하의 질문은 약간의 부정확 한 것 같습니다. 왜 당신이 그들을 갖고 싶어 할, 당신은 "트리"를 가지고 무엇을 의미합니까?

    당신이있어 표는 트리 (대표하는 관계형 방법)입니다.

    당신이 그들을 원하는 경우 쌍을 보유 행 (ID 4, ParentID 0)와 "테이블에서"당신은이 작업을 수행하는 경우 그 엔진 지원을 재귀 SQL의 사용자의 SQL 엔진의 버전이 필요합니다.

    내가 특별히 MySQL을 모르는 것이다, 그러나 나의 이해는 한 번 CONNECT BY와 즉 오라클, 같은 구문을 사용하여 재귀 SQL을 구현할 계획이다.

    당신은 "재귀 쿼리"또는 "CONNECT BY"로 키워드에 대한 내용의 수동의 표에서 보면, 난 당신이 답을 찾을 수있을 것입니다 상상한다.

    (죄송합니다보다 즉시 소비하는 답을 제공 할 수 없다는합니다.)

  7. from https://stackoverflow.com/questions/990529/how-to-find-all-ids-of-children-recursively by cc-by-sa and MIT license