[SQL] 어떻게 MySQL의에서 재귀 SELECT 쿼리를 할까?
SQL어떻게 MySQL의에서 재귀 SELECT 쿼리를 할까?
나는 다음과 같은 테이블을 가지고 :
col1 | col2 | col3
-----+------+-------
1 | a | 5
5 | d | 3
3 | k | 7
6 | o | 2
2 | 0 | 8
"1"에 대한 사용자 검색이 프로그램이 "1"인 COL1 볼 것이다 경우는, 다음 프로그램이 COL1에서 "5"를 검색 계속 COL3 "5"의 값을 얻을 것이다 그것을 얻을 것이다 "3"COL3에서, 등등. 이 인쇄됩니다 그래서 :
1 | a | 5
5 | d | 3
3 | k | 7
"6"에 대한 사용자 검색, 그것은 인쇄됩니다 :
6 | o | 2
2 | 0 | 8
어떻게 그렇게 할 수있는 SELECT 쿼리를 구축?
해결법
-
==============================
1.편집하다
편집하다
@leftclickben 언급 해결 방법도 효과적이다. 우리는 또한 같은위한 저장 프로 시저를 사용할 수 있습니다.
CREATE PROCEDURE get_tree(IN id int) BEGIN DECLARE child_id int; DECLARE prev_id int; SET prev_id = id; SET child_id=0; SELECT col3 into child_id FROM table1 WHERE col1=id ; create TEMPORARY table IF NOT EXISTS temp_table as (select * from table1 where 1=0); truncate table temp_table; WHILE child_id <> 0 DO insert into temp_table select * from table1 WHERE col1=prev_id; SET prev_id = child_id; SET child_id=0; SELECT col3 into child_id FROM TABLE1 WHERE col1=prev_id; END WHILE; select * from temp_table; END //
우리는 출력의 결과를 저장하고 임시 테이블은 같은 세션을 기반으로 우리가 잘못 출력되는 데이터에 관한 문제가되지 않을 것 실 거예요 임시 테이블을 사용하고 있습니다.
SQL 뿐인 데모 이 쿼리 검색 :
SELECT col1, col2, @pv := col3 as 'col3' FROM table1 JOIN (SELECT @pv := 1) tmp WHERE col1 = @pv
| COL1 | COL2 | COL3 | +------+------+------+ | 1 | a | 5 | | 5 | d | 3 | | 3 | k | 7 |
-
==============================
2.데이터가 특정 순서에있는 경우 @Meherzad에 의해 허용 대답에만 작동합니다. 그것은 OP 질문의 데이터로 작업에 발생합니다. 내 경우, 나는 내 데이터와 함께 작동하도록 수정했다.
데이터가 특정 순서에있는 경우 @Meherzad에 의해 허용 대답에만 작동합니다. 그것은 OP 질문의 데이터로 작업에 발생합니다. 내 경우, 나는 내 데이터와 함께 작동하도록 수정했다.
(질문에서 COL1) 모든 레코드의 "ID가"보다 큰 값을 가지고이 비로소 작동을 참고 레코드의 "부모 ID가"(질문에 COL3). 일반적으로 부모가 처음 생성 될 필요가 있기 때문에, 종종 경우입니다. 응용 프로그램이 항목이 다시 부모가 다른 곳에서 할 수있는 계층 구조에 대한 변경을 허용하지만 경우에, 당신은 이것에 의존 할 수 없다.
이것은 사람이 도움이 경우 내 쿼리입니다; 이 데이터가 필요한 구조는 위에서 설명한 주어진 질문 작업을 수행하지 않기 때문에주의.
select t.col1, t.col2, @pv := t.col3 col3 from (select * from table1 order by col1 desc) t join (select @pv := 1) tmp where t.col1 = @pv
차이는 (부모 COL1 값은 어린이의보다 낮기 때문에) 이후에 부모가되도록 해당 표를 COL1으로 정렬되고있다.
-
==============================
3.leftclickben 대답은 나를 위해 일한,하지만 난 루트에 나무까지 주어진 노드의 뒷면에서 경로를 원했고, 이러한 나무 아래, 다른 길을 갈 것 같았다. 그래서 나는 주변 일부 필드를 반전했다 및 명확성을 위해 이름을 변경하고, 나를 위해이 작품은, 경우에 이것은 다른 사람이 너무 ... 원하는 것입니다
leftclickben 대답은 나를 위해 일한,하지만 난 루트에 나무까지 주어진 노드의 뒷면에서 경로를 원했고, 이러한 나무 아래, 다른 길을 갈 것 같았다. 그래서 나는 주변 일부 필드를 반전했다 및 명확성을 위해 이름을 변경하고, 나를 위해이 작품은, 경우에 이것은 다른 사람이 너무 ... 원하는 것입니다
item | parent ------------- 1 | null 2 | 1 3 | 1 4 | 2 5 | 4 6 | 3
과
select t.item_id as item, @pv:=t.parent as parent from (select * from item_tree order by item_id desc) t join (select @pv:=6)tmp where t.item_id=@pv;
제공 :
item | parent ------------- 6 | 3 3 | 1 1 | null
-
==============================
4.저장 프로 시저 그것을 할 수있는 가장 좋은 방법입니다. 데이터가 동일한 순서를 따릅니다 경우 Meherzad의 솔루션은 작동합니다 때문입니다.
저장 프로 시저 그것을 할 수있는 가장 좋은 방법입니다. 데이터가 동일한 순서를 따릅니다 경우 Meherzad의 솔루션은 작동합니다 때문입니다.
우리는이 같은 테이블 구조가있는 경우
col1 | col2 | col3 -----+------+------ 3 | k | 7 5 | d | 3 1 | a | 5 6 | o | 2 2 | 0 | 8
그것은 작동 실 거예요. SQL 바이올린 데모
여기서이를 달성하는 샘플 순서 코드이다.
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.당신이 자식 ID보다 낮은해야하는 부모 ID의 문제없이 선택을 할 수있게하려면, 함수가 사용될 수있다. 또한 여러 아이들을 지원 (나무가해야 할로)과 나무는 여러 개의 머리를 할 수 있습니다. 또한 루프가 데이터에있는 경우 휴식을 보장합니다.
당신이 자식 ID보다 낮은해야하는 부모 ID의 문제없이 선택을 할 수있게하려면, 함수가 사용될 수있다. 또한 여러 아이들을 지원 (나무가해야 할로)과 나무는 여러 개의 머리를 할 수 있습니다. 또한 루프가 데이터에있는 경우 휴식을 보장합니다.
나는 테이블 / 컬럼 이름을 통과 할 수 있도록 동적 SQL을 사용하고 싶어하지만, MySQL은 기능이 지원되지 않습니다.
DELIMITER $$ CREATE FUNCTION `isSubElement`(pParentId INT, pId INT) RETURNS int(11) DETERMINISTIC READS SQL DATA BEGIN DECLARE isChild,curId,curParent,lastParent int; SET isChild = 0; SET curId = pId; SET curParent = -1; SET lastParent = -2; WHILE lastParent <> curParent AND curParent <> 0 AND curId <> -1 AND curParent <> pId AND isChild = 0 DO SET lastParent = curParent; SELECT ParentId from `test` where id=curId limit 1 into curParent; IF curParent = pParentId THEN SET isChild = 1; END IF; SET curId = curParent; END WHILE; RETURN isChild; END$$
여기에 테이블 테스트는 당신의 진짜 이름을 조정해야 할 수있는 실제 테이블 이름과 열 (ParentId, 아이디)를 수정할 수 있습니다.
사용법 :
SET @wantedSubTreeId = 3; SELECT * FROM test WHERE isSubElement(@wantedSubTreeId,id) = 1 OR ID = @wantedSubTreeId;
결과 :
3 7 k 5 3 d 9 3 f 1 5 a
테스트 생성을위한 SQL :
CREATE TABLE IF NOT EXISTS `test` ( `Id` int(11) NOT NULL, `ParentId` int(11) DEFAULT NULL, `Name` varchar(300) NOT NULL, PRIMARY KEY (`Id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; insert into test (id, parentid, name) values(3,7,'k'); insert into test (id, parentid, name) values(5,3,'d'); insert into test (id, parentid, name) values(9,3,'f'); insert into test (id, parentid, name) values(1,5,'a'); insert into test (id, parentid, name) values(6,2,'o'); insert into test (id, parentid, name) values(2,8,'c');
편집 : 여기에 스스로를 테스트 할 수있는 바이올린입니다. 그것은 미리 정의 된 하나를 사용하여 구분 기호를 변경하라고 강요하지만, 그것을 작동합니다.
-
==============================
6.마스터 디종 오프 구축
마스터 디종 오프 구축
(상위 작업을 포함하거나 특정 깊이에서 검색 로직을 사용하려는 경우) 깊이를 반환하는 추가 유틸리티를 제공합니다 여기에 단순화 기능
DELIMITER $$ FUNCTION `childDepth`(pParentId INT, pId INT) RETURNS int(11) READS SQL DATA DETERMINISTIC BEGIN DECLARE depth,curId int; SET depth = 0; SET curId = pId; WHILE curId IS not null AND curId <> pParentId DO SELECT ParentId from test where id=curId limit 1 into curId; SET depth = depth + 1; END WHILE; IF curId IS NULL THEN set depth = -1; END IF; RETURN depth; END$$
용법:
select * from test where childDepth(1, id) <> -1;
from https://stackoverflow.com/questions/16513418/how-to-do-the-recursive-select-query-in-mysql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 카테고리 별 최신 네 개의 항목을 선택하려면? (0) | 2020.03.09 |
---|---|
[SQL] SQL 다중 열 정렬 (0) | 2020.03.09 |
[SQL] 어떻게 시간에 날짜 시간을 캐스팅 (0) | 2020.03.09 |
[SQL] ANSI는 대 비 ANSI 쿼리가 다르게 수행 가입 가입 할 것인가? (0) | 2020.03.09 |
[SQL] 테이블이 주어진 스키마에 존재하는지 확인하는 방법 (0) | 2020.03.09 |