재귀 자기 조인 있는 테이블을

나는 comments이것을 단순화 할 수 있는 테이블을 가지고 있다 :

comments
=======
id
user_id
text
parent_id

여기서 parent_idnull은 허용되지만 상위 주석의 키일 수 있습니다.


이제 select특정 의견의 모든 후손을 어떻게 할 수 있습니까?
댓글이 여러 수준 아래로 떨어질 수 있습니다 …



답변

재귀 쿼리가 알려진 계층 적 쿼리는 MySQL에서 지원되지 않습니다.

그러나 Oracle, Microsoft SQL Server, DB2 및 PostgreSQL에서 지원됩니다.

해결 방법이 필요한 경우 /programming/8104187/mysql-hierarchical-queries 에서 역동적이고 잠재적으로 위험한 트릭을 찾을 수 있습니다.

당신은 또한보다 다른 모델과 계층 적 데이터를 저장하는 방법에 대한 토론을 찾을 수 인접성 (adjacency) 목록 (즉, 부모 여기 열) : /programming/192220/what-is-the-most-efficient- 우아한 길을 파싱 평면 테이블 나무로 /

행운을 빕니다!


답변

이 테이블 디자인은 Bill Karwin ( SQL Antipatterns Strike Back 프레젠테이션의 슬라이드 48에서 시작)에 설명 된대로 SQL 반 패턴 “순진한 나무” 입니다. 이 디자인의 문제는 특히 노드의 모든 자손 (또는 부모)을 얻는 데 어려움이 있다는 것입니다. MySQL을 사용하고 있으므로 다른 RDBMS에있는 공통 테이블 표현식 (with 문 및 RECURSIVE 수정 자)을 사용할 수 없습니다.

당신이 남은 것은 :

  • 계층 적 데이터 구조의 대체 구현 사용 ( 이 질문에 대한 답변은 이에 대한 좋은 참조 일 수 있음)
  • 깊이 제한으로 자체 조인 쿼리를 작성하십시오. 깊이 = 5의 경우 다음 줄에 무언가를 사용할 수 있습니다.

    SELECT *
    FROM comments AS c1
      JOIN comments AS c2 ON (c2.parent_id = c1.id)
      JOIN comments AS c3 ON (c3.parent_id = c2.id)
      JOIN comments AS c4 ON (c4.parent_id = c3.id)
      JOIN comments AS c5 ON (c5.parent_id = c4.id)
  • WITH RECURSIVE를 지원하는 RDBMS를 사용하십시오 (대부분의 사람들에게는 이것이 옵션이 아닐 수도 있음)


답변

MySQL은 필요한 쿼리와 같은 재귀 쿼리를 지원하지 않습니다.

내가 얼마 전에했던 것은 그렇게하기위한 모델을 제공하는 저장 프로 시저를 작성하는 것이 었습니다.

바퀴를 재발 명하기보다는, 과거의 게시물에 대한 링크를 제공합니다.

요컨대, 내가 만든 저장 프로 시저는 대기열 처리를 사용하여 트리를 사전 주문합니다.

  • GetParentIDByID
  • GetAncestry
  • GetFamilyTree

모든 자녀의 부모 (예 : GetFamilyTree 저장 프로 시저)

  • STEP01) parent_id대기열에서 시작
  • STEP02) 다음 parent_id전류를 대기열에서 제외
  • STEP03) id현재의 모든 값을 큐에 넣습니다parent_id
  • STEP04) 코멘트 인쇄 또는 수집
  • STEP05) 대기열이 비어 있지 않으면 STEP02
  • STEP06) 끝났습니다 !!!

모든 부모의 자녀 (예 : GetAncestry 저장 프로 시저)

  • STEP01) id대기열에서 시작
  • STEP02) 다음 id전류를 대기열에서 제외
  • STEP03) parent_id전류 값을 큐에 넣는다id
  • STEP04) 코멘트 인쇄 또는 수집
  • STEP05) 대기열이 비어 있지 않으면 STEP02
  • STEP06) 끝났습니다 !!!

구현 내용을 보려면 다른 게시물의 저장 프로 시저를 살펴보십시오.

시도 해봐 !!!


답변

SELECT  group_concat(@id :=
        (
        SELECT  id
        FROM    comments
        WHERE   parent_id = @id
        )) AS comment
FROM    (
        SELECT  @id := 1
        ) vars
STRAIGHT_JOIN
        comments
WHERE   @id IS NOT NULL

깡깡이