복붙노트

[SQL] 하나 개의 SQL 쿼리에서 모든 상위 행을 얻기

SQL

하나 개의 SQL 쿼리에서 모든 상위 행을 얻기

나는 범주의 목록이 포함 된 간단한 MySQL의 테이블, 레벨이 PARENT_ID에 의해 결정됩니다 있습니다 :

id  name    parent_id
---------------------------
1   Home        0
2   About       1
3   Contact     1
4   Legal       2
5   Privacy     4
6   Products    1
7   Support     1

나는 이동 경로 추적을 시도하고있다. 내가 아이의 'ID를'그래서, 나는 (우리는 "홈"0에 도달 할 때까지 체인을 반복) 사용 가능한 모든 부모 싶어. 무제한 깊이에가는 숫자 또는 자녀 행이있을 수 있습니다.

현재 나는 각 부모에 대한 SQL 호출을 사용하고,이 지저분합니다. 하나 개의 쿼리에서이 모든 작업을 수행하는 SQL의 방법이 있나요?

해결법

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

    1.여기에서 적응 :

    여기에서 적응 :

    SELECT T2.id, T2.name
    FROM (
        SELECT
            @r AS _id,
            (SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id,
            @l := @l + 1 AS lvl
        FROM
            (SELECT @r := 5, @l := 0) vars,
            table1 h
        WHERE @r <> 0) T1
    JOIN table1 T2
    ON T1._id = T2.id
    ORDER BY T1.lvl DESC
    

    라인 @r = 5는 현재 페이지의 페이지 번호입니다. 결과는 다음과 같습니다

    1, 'Home'
    2, 'About'
    4, 'Legal'
    5, 'Privacy'
    
  2. ==============================

    2.마크 바이어스에 의해 끝내 대답!

    마크 바이어스에 의해 끝내 대답!

    파티에 늦게 어쩌면 조금,하지만 당신은 또한 (데이터가 손상되었을 때 즉 어떻게 든) ID가 = PARENT_ID,이 같은 대답을 확장 할 수 있습니다 때 무한 루프를 방지하려면 :

        SELECT T2.id, T2.name
        FROM (
            SELECT
                @r AS _id,
                @p := @r AS previous,
                (SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id,
                @l := @l + 1 AS lvl
            FROM
                (SELECT @r := 5, @p := 0, @l := 0) vars,
                table1 h
            WHERE @r <> 0 AND @r <> @p) T1
        JOIN table1 T2
        ON T1._id = T2.id
        ORDER BY T1.lvl DESC
    
  3. ==============================

    3.위의 방법 외에도 :

    위의 방법 외에도 :

    post
    -----
    id
    title
    author
    
    author
    ------
    id
    parent_id
    name
    
    
    [post]
    
    id  | title | author |  
    ----------------------
    1   | abc   | 3      |
    
    
    [author]
    
    | id    | parent_id | name  |   
    |---------------------------|
    | 1     | 0         | u1    |
    | 2     | 1         | u2    |
    | 3     | 2         | u3    |
    | 4     | 0         | u4    |
    

    부모를 포함하여 저자는 게시물에 액세스 할 수 있습니다.

    나는 저자가 포스트에 액세스 할 수 있는지 여부를 확인합니다.

    해결책:

    게시물 작성자의 ID를주고 모든 저자와 저자의 부모를 반환

    SELECT T2.id, T2.username 
    FROM (
        SELECT @r AS _id, 
            (SELECT @r := parent_id FROM users WHERE id = _id) AS parent_id,
            @l := @l + 1
        FROM
            (SELECT @r := 2, @l := 0) vars, 
            users h     
        WHERE @r <> 0) T1 JOIN users T2 
    ON T1._id = T2.id;
    

    @r : @r 변수 = 2 => 할당 값.

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

    4.나는 하나의 쿼리를 사용하여이 작업을 수행하는 쉬운 방법이 없다 생각합니다.

    나는 하나의 쿼리를 사용하여이 작업을 수행하는 쉬운 방법이 없다 생각합니다.

    나는 당신의 요구에 맞게 보인다 중첩 된 세트를 살펴, 취할 추천 할 것입니다.

  5. ==============================

    5.당신은 ID 대신 슬러그 경우 단순히 자식 카테고리의 ID를 찾을 하위 쿼리를 실행합니다. 표 - 카테고리 | ID | parentId | 슬러그 | | ------------------------- | | 1 | 0 | U1 | | 2 | 1 | U2 | | 3 | 2 | U3 | | 4 | 0 | U4 |

    당신은 ID 대신 슬러그 경우 단순히 자식 카테고리의 ID를 찾을 하위 쿼리를 실행합니다. 표 - 카테고리 | ID | parentId | 슬러그 | | ------------------------- | | 1 | 0 | U1 | | 2 | 1 | U2 | | 3 | 2 | U3 | | 4 | 0 | U4 |

    SELECT T2.id, T2.slug
    FROM (
        SELECT
            @r AS _id,
            (SELECT @r := parentId FROM categories WHERE id = _id) AS parentId,
            @l := @l + 1 AS lvl
        FROM
            (SELECT @r := (SELECT id FROM categories WHERE slug = 'u3'), @l := 0) vars,
            categories h
        WHERE @r <> 0) T1
    JOIN categories T2
    ON T1._id = T2.id
    ORDER BY T1.lvl DESC
    
  6. ==============================

    6.나는 무엇이든지 더 읽을 수 있도록 예제로 이전 답변을 사용했다.

    나는 무엇이든지 더 읽을 수 있도록 예제로 이전 답변을 사용했다.

    SELECT  @org_id as id,
        (SELECT name FROM test.organizations WHERE id = @org_id) as name,
        (SELECT @org_id := parent_id FROM test.organizations WHERE id = @org_id) AS parent_id
    FROM (SELECT @org_id := 4) vars, test.organizations org
    WHERE @org_id is not NULL
    ORDER BY id;
    

    같은 실행 외모의 결과 :

    (단지 빠른 경우) 당신이 데이터베이스 테스트에 질문에서 값을 입력 할 필요가 스스로를 확인하려면, 테이블 조직

    CREATE TABLE organizations(
    id        int(11) NOT NULL AUTO_INCREMENT,
    name      varchar(45) DEFAULT NULL,
    parent_id int(11)     DEFAULT NULL,
    PRIMARY KEY (id));
    
    insert into organizations values(1, "home", null);
    insert into organizations values(2, "about", 1);
    insert into organizations values(3, "contact", 1);
    insert into organizations values(4, "legal", 2);
    insert into organizations values(5, "privacy", 4);
    insert into organizations values(6, "products", 1);
    insert into organizations values(7, "support", 1);
    
  7. ==============================

    7.あふぁい K의.

    あふぁい K의.

    이 Sitepoint 기사는 당신을 도울 수 있습니다.

    당신은, 하나 개의 쿼리로 모든 요소를 ​​검색으로 반복을 배열에 저장 한 후 수 등이 여기와 여기에 설명

  8. from https://stackoverflow.com/questions/2441821/getting-all-parent-rows-in-one-sql-query by cc-by-sa and MIT license