복붙노트

[SQL] MySQL을위한 이전에 상응하여 연결

SQL

MySQL을위한 이전에 상응하여 연결

모두,

나는 MySQL 데이터베이스 버전 5.0에서 부모 자식 관계의 존재를 정의하는 테이블에 세 개의 필드가 있습니다. 테이블 이름은 tb_Tree이며 다음과 같은 데이터가 있습니다 :

Table Name: tb_Tree

Id | ParentId | Name
--------------------
1  | 0        | Fruits
2  | 0        | Vegetables
3  | 1        | Apple
4  | 1        | Orange
5  | 2        | Cabbage
6  | 2        | Eggplant

어떻게이 ParentId가 지정된 경우 쿼리가 모든 아이를 얻기 위해 쓰기 않습니다. 주어진 테이블 항목은 단지 샘플 데이터이며, 그들은 더 많은 행을 가질 수 있습니다. 오라클은 "CONNECT BY PRIOR"절을 가지고,하지만 난 MySQL 용 유사한 아무것도 찾지 못했습니다. 사람이 조언을 기쁘게 할 수 있습니까?

감사

해결법

  1. ==============================

    1.당신이 어려운 방법을해야하므로 MySQL은 재귀 쿼리를 지원하지 않습니다 :

    당신이 어려운 방법을해야하므로 MySQL은 재귀 쿼리를 지원하지 않습니다 :

    당신이 최대 깊이를 알고 있다면 당신은 가능한 최대 깊이에게 (왼쪽 외부 조인 사용) 자체에 테이블을 가입 할 수 있습니다 다음 null을 정리.

    또한 중첩 된 세트에 트리 표현을 변경할 수 있습니다.

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

    2.또한 우리는 MySQL의에서 비슷한 결과를 얻을 수있는 방법을 보여줍니다 흥미로운 블로그로 볼 수

    또한 우리는 MySQL의에서 비슷한 결과를 얻을 수있는 방법을 보여줍니다 흥미로운 블로그로 볼 수

    http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/

  3. ==============================

    3.이 오래된 스레드,하지만 난 다른 포럼에 질문을 가지고 있기 때문에 나는 여기에 추가 거라고 생각했다. 이 경우, 나는 특정 사건을 처리하기 위해 하드 코딩 된 저장 프로 시저를 만들었습니다. 모든 사용자가 그럼에도 불구하고 의지에서 저장 프로 시저 만 만들 수 있기 때문에이 할 일이 물론 몇 가지 단점이있다.

    이 오래된 스레드,하지만 난 다른 포럼에 질문을 가지고 있기 때문에 나는 여기에 추가 거라고 생각했다. 이 경우, 나는 특정 사건을 처리하기 위해 하드 코딩 된 저장 프로 시저를 만들었습니다. 모든 사용자가 그럼에도 불구하고 의지에서 저장 프로 시저 만 만들 수 있기 때문에이 할 일이 물론 몇 가지 단점이있다.

    노드와 아이들과 함께 다음 표를 고려 ​​:

    CREATE TABLE nodes (
           parent INT,
           child INT
    );
    
    INSERT INTO nodes VALUES
           ( 5,  2), ( 5, 3),
           (18, 11), (18, 7),
           (17,  9), (17, 8),
           (26, 13), (26, 1), (26,12),
           (15, 10), (15, 5),       
           (38, 15), (38, 17), (38, 6),
           (NULL, 38), (NULL, 26), (NULL, 18);
    

    이 테이블은 다음 프로 시저를 제공하는 노드의 모든 사망자 구성된 결과 집합을 계산한다 :

    delimiter $$
    CREATE PROCEDURE find_parts(seed INT)
    BEGIN
      -- Temporary storage
      DROP TABLE IF EXISTS _result;
      CREATE TEMPORARY TABLE _result (node INT PRIMARY KEY);
    
      -- Seeding
      INSERT INTO _result VALUES (seed);
    
      -- Iteration
      DROP TABLE IF EXISTS _tmp;
      CREATE TEMPORARY TABLE _tmp LIKE _result;
      REPEAT
        TRUNCATE TABLE _tmp;
        INSERT INTO _tmp SELECT child AS node
          FROM _result JOIN nodes ON node = parent;
    
        INSERT IGNORE INTO _result SELECT node FROM _tmp;
      UNTIL ROW_COUNT() = 0
      END REPEAT;
      DROP TABLE _tmp;
      SELECT * FROM _result;
    END $$
    delimiter ;
    
  4. ==============================

    4.선택 목록 아래의 모든 식물과 4 레벨까지 자신의 parentid는 (물론 당신은 수준을 확장 할 수 있습니다)

    선택 목록 아래의 모든 식물과 4 레벨까지 자신의 parentid는 (물론 당신은 수준을 확장 할 수 있습니다)

    select id, name, parentid
    ,(select parentid from tb_tree where id=t.parentid) parentid2
    ,(select parentid from tb_tree where id=(select parentid from tb_tree where id=t.parentid)) parentid3
    ,(select parentid from tb_tree where id=(select parentid from tb_tree where id=(select parentid from tb_tree where id=t.parentid))) parentid4 
    from tb_tree t
    

    다음은 최종 결과를 얻기 위해이 쿼리를 사용할 수 있습니다. 예를 들어, 당신은 SQL 아래로 "과일"의 모든 자식을 얻을 수 있습니다 :

    select id ,name from (
        select id, name, parentid
        ,(select parentid from tb_tree where id=t.parentid) parentid2
        ,(select parentid from tb_tree where id=(select parentid from tb_tree where id=t.parentid)) parentid3
        ,(select parentid from tb_tree where id=(select parentid from tb_tree where id=(select parentid from tb_tree where id=t.parentid))) parentid4 
        from tb_tree t) tt
    where ifnull(parentid4,0)=1 or ifnull(parentid3,0)=1 or ifnull(parentid2,0)=1 or ifnull(parentid,0)=1
    
  5. ==============================

    5.후반 게시 될 수 있습니다.

    후반 게시 될 수 있습니다.

    MySQL8하면 재귀 절을 달성 할 수있다. 다음은 예이다.

     with recursive cte (id, name, parent_id) as (
      select     id,
                 name,
                 parent_id
      from       products
      where      parent_id = 19
      union all
      select     p.id,
                 p.name,
                 p.parent_id
      from       products p
      inner join cte
              on p.parent_id = cte.id
    )
    select * from cte;
    

    자세한 도움말을 다른 스레드를 찾을 희망이 사람을 도움이 될 것입니다.

  6. ==============================

    6.아래 프로 시저 순서 이전에 다시 참조 행이 표. 내가 임시 테이블에 행을 복사하는 첫 번째 단계에 공지 사항 - 해당 행이 어떤 조건을 일치합니다. 제 경우라면 (GPS 네비게이션에 사용되는도) 같은 선형에 속하는 행이다. 비즈니스 도메인은 중요하지 않습니다. 그냥 내 경우에는 나는 같은 길에 속하는 세그먼트를 정렬하고

    아래 프로 시저 순서 이전에 다시 참조 행이 표. 내가 임시 테이블에 행을 복사하는 첫 번째 단계에 공지 사항 - 해당 행이 어떤 조건을 일치합니다. 제 경우라면 (GPS 네비게이션에 사용되는도) 같은 선형에 속하는 행이다. 비즈니스 도메인은 중요하지 않습니다. 그냥 내 경우에는 나는 같은 길에 속하는 세그먼트를 정렬하고

    DROP PROCEDURE IF는 orderLocations 존재; DELIMITER //

    절차의 orderLocations를 CREATE (_full_linear_code VARCHAR (11))   BEGIN

    DECLARE _code VARCHAR(11);
    DECLARE _id INT(4);
    DECLARE _count INT(4);
    DECLARE _pos INT(4);
    
    DROP TEMPORARY TABLE IF EXISTS temp_sort;
    
    CREATE TEMPORARY TABLE temp_sort (
      id              INT(4) PRIMARY KEY,
      pos             INT(4),
      code            VARCHAR(11),
      prev_code       VARCHAR(11)
    );
    
    -- copy all records to sort into temp table - this way sorting would go all in memory
    INSERT INTO temp_sort SELECT
                             id, -- this is primary key of original table
                             NULL, -- this is position that still to be calculated
                             full_tmc_code, -- this is a column that references sorted by
                             negative_offset -- this is a reference to the previous record (will be blank for the first)
                           FROM tmc_file_location
                           WHERE linear_full_tmc_code = _full_linear_code;
    
    -- this is how many records we have to sort / update position
    SELECT count(*)
    FROM temp_sort
    INTO _count;
    
    -- first position index
    SET _pos = 1;
    
    -- pick first record that has no prior record
    SELECT
      code,
      id
    FROM temp_sort l
    WHERE prev_code IS NULL
    INTO _code, _id;
    
    -- update position of the first record
    UPDATE temp_sort
    SET pos = _pos
    WHERE id = _id;
    
    -- all other go by chain link
    WHILE (_pos < _count) DO
      SET _pos = _pos +1;
    
      SELECT
        code,
        id
      FROM temp_sort
      WHERE prev_code = _code
      INTO _code, _id;
    
    
      UPDATE temp_sort
      SET pos = _pos
      WHERE id = _id;
    
    END WHILE;
    
    -- join two tables and return position along with all other fields
    SELECT
      t.pos,
      l.*
    FROM tmc_file_location l, temp_sort t
    WHERE t.id = l.id
    ORDER BY t.pos;
    
    END;
    
  7. from https://stackoverflow.com/questions/7631048/connect-by-prior-equivalent-for-mysql by cc-by-sa and MIT license