이베리스
Iberis
이베리스
전체 방문자
오늘
어제
  • 전체보기 (72)
    • Course (64)
      • MS-SQL (10)
      • MY-SQL (12)
      • Oracle (2)
      • PostgreSQL (1)
      • ASP.NET with C# (5)
      • PHP (14)
      • Java (1)
      • javaScript (11)
      • A quick tip (1)
      • CodeIgniter (1)
      • CSS (3)
      • 운영체제 (2)
      • Git (1)
      • 리눅스 (0)
    • Utility (4)
    • 와우 (2)
      • 애드온 (2)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • 1326
  • Benik
  • 자동 줄 바꿈
  • 테이블 복사
  • 19c
  • 접속안됨
  • 렌카드
  • 보안 주체
  • comma
  • width
  • Elv
  • wowclassic
  • 삭제
  • error
  • 테이블
  • 와우클래식
  • 공유폴더
  • 3자리
  • power point
  • 수동삭제
  • 구조 복사
  • share
  • 쿼리
  • dbo
  • 3DP
  • MSSQL
  • 콤마
  • 이베리스
  • table
  • 15517

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
이베리스

Iberis

Course/MY-SQL

MySql 계층적 조회 쿼리

2015. 5. 12. 09:18
MySQL 에는 안타깝게도 Oracle 의 start with, connect by 를 지원하는 함수가 없다.

때문에 아래와 같이 function 을 만들어서 사용한다.

예제 테이블) test.servers_group

create table test.servers_group 
(
 group_idx int auto_increment,     // P.K
 group_name varchar(40),           // group name
 group_depth int,                       // level
 group_order int,                        // group 순서
 parent_idx int,                          // parent group_idx
 manager_idx,                           // 관리자 idx (test.managers_info.idx)
 primary key(group_idx) 
)
----------------------------------------------------------------------------------
>> Create Function 
CREATE FUNCTION start_with_connect_by(value INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
        DECLARE _id INT;
        DECLARE _parent INT;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

        SET _parent = @id;
        SET _id = -1;

        IF @id IS NULL THEN
                RETURN NULL;
        END IF;

        LOOP
                SELECT  MIN(group_idx)
                INTO    @id
                FROM    test.servers_group
                WHERE   parent_idx = _parent
                        AND group_idx > _id;
                IF @id IS NOT NULL OR _parent = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @id;
                END IF;
                SET @level := @level - 1;
                SELECT  group_idx, parent_idx
                INTO    _id, _parent
                FROM    test.servers_group
                WHERE   group_idx = _parent;
        END LOOP;
END
----------------------------------------------------------------------------------
>> 사용
SELECT  CONCAT(REPEAT('   ', group_depth - 1), CAST(sg.group_idx AS CHAR)) AS group_idx, group_name, parent_idx, group_depth, manager_idx
FROM    (
        SELECT  start_with_connect_by(group_idx) AS id, @level AS level
        FROM    (
                SELECT  @start_with := 0,
                        @id := @start_with,
                        @level := 0
                ) vars, test.servers_group
        WHERE   @id IS NOT NULL
        ) sg2
JOIN    test.servers_group sg
ON      sg.group_idx = sg2.id;





===================================================================================
Function 만들기 다른 예제 

CREATE TABLE test.dept_code ( 
code VARCHAR(50), 
name VARCHAR(50), 
parent_code VARCHAR(50) 
);
INSERT INTO test.dept_code VALUES( 'A001', '연구소' , '');
INSERT INTO test.dept_code VALUES( 'A002', '솔루션사업본부' , '');
INSERT INTO test.dept_code VALUES( 'A003', '기술지원부', '' );
INSERT INTO test.dept_code VALUES( 'A004', '개발1팀' , 'A001');
INSERT INTO test.dept_code VALUES( 'A005', '개발2팀' , 'A001');
INSERT INTO test.dept_code VALUES( 'A006', 'OJT' , 'A005');

CREATE FUNCTION GET_DEPT_TREE(value VARCHAR(50)) RETURNS VARCHAR(50) 
NOT DETERMINISTIC
READS SQL DATA
BEGIN
        DECLARE _code VARCHAR(50);
        DECLARE _parent VARCHAR(50);
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @code = NULL;

        SET _parent = @code;
        SET _code = '';
        
        IF @code IS NULL THEN
                RETURN NULL;
        END IF;

       LOOP
                SELECT  MIN(code)
                INTO    @code
                FROM    test.dept_code
                WHERE   parent_code = _parent
                        AND code > _code;
                IF @code IS NOT NULL OR _parent = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @code;
                END IF;
                SET @level := @level - 1;
                SELECT  code, parent_code
                INTO    _code, _parent
                FROM    test.dept_code
                WHERE   code = _parent;
        END LOOP;
END


SELECT  dc.code, CONCAT(REPEAT('       ', dc2.lev-1), name) AS name, parent_code, CAST(dc2.lev AS CHAR) AS lev
FROM    (
        SELECT  GET_DEPT_TREE(code) AS code, @level as lev
        FROM    (
                SELECT  @start_with := '',
                        @code := @start_with,
                        @level := 0
                ) vars, test.dept_code
        WHERE   @code IS NOT NULL
        ) dc2
JOIN    test.dept_code dc
ON      dc.code = dc2.code;


저작자표시 비영리 변경금지 (새창열림)

'Course > MY-SQL' 카테고리의 다른 글

mysql 한글 깨짐 문제 해결  (0) 2015.11.23
MySQL : 테이블 복사 (다른 DB간 테이블 복사 포함)  (0) 2015.10.14
MSSQL에서 MySQL 스토어드 프로시저(Stored PROCEDURE) 변경방법  (0) 2015.04.30
MySQL row_number 구현  (0) 2015.04.28
[mysql] 쿼리값이 NULL 일때 0으로 바꾸기  (0) 2014.09.01
    'Course/MY-SQL' 카테고리의 다른 글
    • mysql 한글 깨짐 문제 해결
    • MySQL : 테이블 복사 (다른 DB간 테이블 복사 포함)
    • MSSQL에서 MySQL 스토어드 프로시저(Stored PROCEDURE) 변경방법
    • MySQL row_number 구현
    이베리스
    이베리스
    Developer

    티스토리툴바