복붙노트

[SQL] @ 기호 - MySQL의에서 재귀 SELECT 질의에 대한 해결책?

SQL

@ 기호 - MySQL의에서 재귀 SELECT 질의에 대한 해결책?

이 MySQL의에서 재귀 SELECT 쿼리에 대한 질문이 많이 있지만, 답변의 대부분은 그 "MySQL의에서 재귀 SELECT 쿼리에 대한이 해결책"입니다.

사실이 특정 솔루션입니다 및이 질문은에서 찾을 수 있습니다 이전 질문의 다음 그래서 내가 분명하게 알고 싶어 (방법은 - 어떻게 - 더 - 재귀 선택 쿼리 -에 - MySQL의)

이 테이블이 있다고 가정 :

col1 - col2 - col3
1    -  a   -  5
5    -  d   -  3
3    -  k   -  7
6    -  o   -  2
2    -  0   -  8

& 당신은 당신이 밖으로 인쇄 할 즉 COL1의 값 "1"에 연결하는 모든 링크를 찾으려면 :

1 - a - 5
5 - d - 3
3 - k - 7

그럼 당신은이 간단한 쿼리를 사용할 수 있습니다 :

select col1, col2, @pv:=col3 as 'col3' from table1
join
(select @pv:=1)tmp
where col1=@pv

좋아, 좋아, 그러나, 당신의 표는 COL1, 전에서 "3"를 포함하는 COL1에 "1"을 포함하는 2 개 기록 및 2 개 기록이있는 경우 :

col1 - col2 - col3
1    -  a   -  5
1    -  m   -  9
5    -  d   -  3
3    -  k   -  7
6    -  o   -  2
3    -  v   -  10
2    -  0   -  8

사용자가 COL1에 "1"을 검색 할 때 다음, 그것은이 "1"에 연결하는 모든 링크를 표시한다, 즉, 그것은이 기대 결과를 표시해야합니다 :

col1 - col2 - col3
1    -  a   -  5
1    -  m   -  9
5    -  d   -  3
3    -  k   -  7
3    -  v   -  10

그래서, 내 질문은이 결과를 기대하고 위의 모든 링크를 보여줄 수 있도록 우리가 위의 쿼리를 수정합니까 어떻게?

편집 : @ 고든, 우리는 그때부터이 쿼리 수단 뭔가를 별개의 COL1, COL2를 선택 생략하면, 당신은합니다 (childID이 증가되었다 때문에, 그래서 우리는 표를 주문할 수)이 작업 할 수 있습니다 :

select col1, col2,
         @pv:=(case when find_in_set(col3, @pv) then @pv else concat(@pv, ',', col3) 
               end) as 'col3'
  from (select * from table1 order by col1) tb1 join
      (select @pv:='1') tmp
      on find_in_set(col1, @pv) > 0

이 데이터 인 경우이 경우, 우리는, 예를 들어, 순서에 대해 걱정하지 마십시오 :

col1 - col2 - col3
4    -  a   -  5
1    -  d   -  2
1    -  k   -  4
2    -  o   -  3
6    -  k   -  8
8    -  o   -  9

출력은 다음과 같습니다

col1 - col2 - col3
1    -  d   -  1,2
1    -  k   -  1,2,4
2    -  o   -  1,2,4,3

그래서 우리는이 결과를 1,2,4,3 권리를 얻을? COL1이 1,2,4,3 인 경우 & 우리는 모든 레코드를 선택합니다. 그런 다음 우리는 최종 예상 된 결과를 얻을 수 있습니다.

이런 경우, 당신은 솔루션 배제 내가 방금 언급 한 특별한 경우를 생각할 수?

해결법

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

    1.I는 다음과 같이 일하는 것이 궁금 유지 :

    I는 다음과 같이 일하는 것이 궁금 유지 :

    select distinct col1, col2
    from (select col1, col2,
                 @pv:=(case when find_in_set(col3, @pv) then @pv else concat(@pv, ',', col3) 
                       end) as 'col3'
          from table1 join
              (select @pv:='1') tmp
              on find_in_set(col1, @pv) > 0
         ) t
    

    이런 식으로 뭔가 작은 데이터 세트에 대해 작동합니다. 그러나, 문자열의 모든 ID를두기의 아이디어는 문자열의 용량으로 제한됩니다.

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

    2.더 플레이했다. 이 때문에 항목의 순서에 사용자 변수를 사용하여 작업을 가져올 수 없습니다.

    더 플레이했다. 이 때문에 항목의 순서에 사용자 변수를 사용하여 작업을 가져올 수 없습니다.

    당신이 수준의 합리적인 최대 번호가 그러나 경우에 당신은 이런 식으로 뭔가를 할 수 : -

    SELECT CONCAT_WS('-', a.allCols, b.allCols, c.allCols, d.allCols, e.allCols, f.allCols, g.allCols, h.allCols, i.allCols, j.allCols, k.allCols, l.allCols, m.allCols)
    FROM (SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) a
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) b ON a.col3 = b.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) c ON b.col3 = c.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) d ON c.col3 = d.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) e ON d.col3 = e.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) f ON e.col3 = f.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) g ON f.col3 = g.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) h ON g.col3 = h.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) i ON h.col3 = i.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) j ON i.col3 = j.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) k ON j.col3 = k.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) l ON k.col3 = l.col1
    LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) m ON l.col3 = m.col1
    WHERE a.col1 = 1
    

    이것은 13 레벨 (OK, 테스트 데이터에 사용되는 단지 몇)까지에 대처하고, 각 행은 대시로 합류와 쉼표, 각 열에 대한 비트를 분리 줄 것입니다 (-).

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

    3.계층 구조 수준의 내 제한 깊은, 나는 다음을 사용 :

    계층 구조 수준의 내 제한 깊은, 나는 다음을 사용 :

    부모님:

    select * from mytable
    join (
        select A.id Aid,B.id Bid, C.id Cid, D.id Did, E.id Eid, F.id Fid,G.id Gid, H.id Hid from mytable A
        left join mytable B on B.id=A.parent
        left join mytable C on C.id=B.parent
        left join mytable D on D.id=C.parent
        left join mytable E on E.id=D.parent
        left join mytable F on F.id=E.parent
        left join mytable G on G.id=F.parent
        left join mytable H on H.id=G.parent
        where A.id=9
    ) X
    where id in (Aid,Bid,Cid,Did,Eid,Fid,Gid,Hid);
    

    어린이:

    select * from mytable where id in (
    select distinct id from mytable
    join (
        select A.id Aid,B.id Bid, C.id Cid, D.id Did, E.id Eid, F.id Fid,G.id Gid, H.id Hid FROM mytable A
        left join mytable B on B.parent=A.id
        left join mytable C on C.parent=B.id
        left join mytable D on D.parent=C.id
        left join mytable E on E.parent=D.id
        left join mytable F on F.parent=E.id
        left join mytable G on G.parent=F.id
        left join mytable H on H.parent=G.id
        Where A.id=1
    ) X
    where id in (Aid,Bid,Cid,Did,Eid,Fid,Gid,Hid)
    

    );

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

    4.저장 프로 시저 그것을 할 수있는 가장 좋은 방법입니다. 데이터가 동일한 순서를 따른다면 고든의 솔루션은 작동합니다 때문입니다.

    저장 프로 시저 그것을 할 수있는 가장 좋은 방법입니다. 데이터가 동일한 순서를 따른다면 고든의 솔루션은 작동합니다 때문입니다.

    우리는이 같은 테이블 구조가있는 경우

    col1 - col2 - col3
    3 - k - 7
    5 - d - 3
    1 - a - 5
    6 - o - 2
    2 - 0 - 8
    

    그것은 작동 실 거예요.

    여기서이를 달성하는 샘플 순서 코드이다.

    delimiter //
    CREATE PROCEDURE chainReaction 
    (
        in inputNo int
    ) 
    BEGIN 
        declare final_id int default NULL;
        SELECT col3 into final_id from table1
        where col1 = inputNo;
        if( final_id is not null) then
            insert into results(select col1, col2, col3 from table1 where col1 = inputNo);
            CALL chainReaction(final_id);   
        end if;
    END//
    delimiter ;
    
    call chainReaction(1);
    select * from results;
    drop table if exists results;
    
  5. from https://stackoverflow.com/questions/16542013/symbol-a-solution-for-recursive-select-query-in-mysql by cc-by-sa and MIT license