database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
ㆍMS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
MS-SQL Q&A 6741 게시물 읽기
No. 6741
tree 구조 sorting 관련 질문드립니다.
작성자
내아음벌집
작성일
2013-09-29 15:36
조회수
9,354

안녕하십니까.

 

 

 

tree구조 쿼리 중 sort 문제가 생겨 질문 드립니다.

 

 

 

table 구조

 

 

 

table명 : t_tree

 

---------------------------------------------------

 

doc_no | parent_doc_no | sort

 

---------------------------------------------------

 

doc_0001 | null | 1

 

doc_00010001 | doc_0001 | 1

 

doc_00010002 | doc_0001 | 2

 

doc_000100010001 | doc_00010001 | 1

 

doc_000100020001 | doc_00010002 | 1

 

doc_0002 | null | 2

 

doc_00020001 | doc_0002 | 1

 

doc_00020002 | doc_0002 | 2

 

doc_000200010001 | doc_00020001 | 1

 

doc_000200020001 | doc_00020002 | 1

 

---------------------------------------------------

 

 

 

위와같은 구조로 되어있구요

 

 

 

sort컬럼의 생성규칙은 해당 depth의 순번입니다.

 

 

 

해당 쿼리는 아래와 같습니다.

 

-------------------------------------------------------------------------------------------

 

with cte(doc_no,parent_doc_no,lvl,sort_cd,sort)

 

as

 

(

 

select doc_no,parent_doc_no,1 as lvl, convert(varchar(max),doc_no),sort

 

from t_tree with(nolock)

 

where parent_no is null

 

union all

 

select a.doc_no, a.parent_doc_no, lvl+1 as lvl, convert(varchar(max),sort_cd+' '+a.doc_no),a.sort

 

from t_tree a with(nolock), cte b

 

where a.parent_doc_no = b.doc_no

 

)

 

select *

 

from cte

 

order by sort_cd,sort

 

--------------------------------------------------------------------------------------------

 

 

 

문제는, 위와 같은 쿼리로 작성 시

 

lvl별로 sorting은 가능하나 sort 컬럼별로는 sorting이 어렵습니다.

 

sort컬럼은 사용자가 직접 입력하는 필드로 sort별 sorting 가능하게 하려면

 

어떤방법을 써야할까요?

 

doc_no 생성규칙을 바꿔야 할 지 sort 컬럼 입력 규칙을 바꿔야 할 지

 

아니면 저 방법대로 쿼리에서 가능한지 고수님들의 답변 부탁드립니다.~~

 

이 글에 대한 댓글이 총 4건 있습니다.
-- 깊이우선탐색
with t_tree( doc_no, parent_doc_no, sort )
as
(
 
SELECT 'doc_0001', null, 1
 
UNION ALL SELECT 'doc_00010001', 'doc_0001', 1
 
UNION ALL SELECT 'doc_00010002', 'doc_0001', 2
 
UNION ALL SELECT 'doc_000100010001', 'doc_00010001', 1
 
UNION ALL SELECT 'doc_000100020001', 'doc_00010002', 1
 
UNION ALL SELECT 'doc_0002', null, 2
 
UNION ALL SELECT 'doc_00020001', 'doc_0002', 1
 
UNION ALL SELECT 'doc_00020002', 'doc_0002', 2
 
UNION ALL SELECT 'doc_000200010001', 'doc_00020001', 1
 
UNION ALL SELECT 'doc_000200020001', 'doc_00020002', 1
 
)
SELECT *
FROM t_tree
ORDER BY doc_no
;

-- 넓이우선탐색

with t_tree( doc_no, parent_doc_no, sort )

as
(
 
SELECT 'doc_0001', null, 1
 
UNION ALL SELECT 'doc_00010001', 'doc_0001', 1
 
UNION ALL SELECT 'doc_00010002', 'doc_0001', 2
 
UNION ALL SELECT 'doc_000100010001', 'doc_00010001', 1
 
UNION ALL SELECT 'doc_000100020001', 'doc_00010002', 1
 
UNION ALL SELECT 'doc_0002', null, 2
 
UNION ALL SELECT 'doc_00020001', 'doc_0002', 1
 
UNION ALL SELECT 'doc_00020002', 'doc_0002', 2
 
UNION ALL SELECT 'doc_000200010001', 'doc_00020001', 1
 
UNION ALL SELECT 'doc_000200020001', 'doc_00020002', 1
 
)
 
, cte(doc_no,parent_doc_no,lvl,sort_cd,sort)
 
as
 
(
 
select doc_no,parent_doc_no,1 as lvl, convert(varchar(max),doc_no),sort
 
from t_tree with(nolock)
 
where parent_doc_no is null
 
union all
 
select a.doc_no, a.parent_doc_no, lvl+1 as lvl, convert(varchar(max),sort_cd+' '+a.doc_no),a.sort
 
from t_tree a with(nolock), cte b
 
where a.parent_doc_no = b.doc_no
 
)
SELECT *
FROM cte
ORDER BY lvl, doc_no
;
 
--문제는 어떤 결과를 원하시는 건지를 잘 모르겠다는거.. O_o;;
우욱님이 2013-09-30 08:48에 작성한 댓글입니다. Edit

답변 감사드립니다.

제가 하고자 하는것은

doc_00010001 | doc_0001 | 1

doc_00010002 | doc_0001 | 2

위의 데이터를

doc_00010001 | doc_0001 | 2

doc_00010002 | doc_0001 | 1

로 sort 컬럼을 변경 했을때 sorting을 다시 하고자 한다는 것입니다.

물론 tree구조대로 나와야하구요. 

좋은팁 부탁드립니다.

내마음벌집님이 2013-09-30 11:02에 작성한 댓글입니다.
이 댓글은 2013-09-30 11:04에 마지막으로 수정되었습니다. Edit

-- 깊이우선탐색 에서 동일한 depth에서는 sort값이 높은 걸 우선 찍어 내려가는 것으로 보고 만들어 봤습니다.

 

with t_tree( doc_no, parent_doc_no, sort )
as
(
 
SELECT 'doc_0001', null, 1
 
UNION ALL SELECT 'doc_00010001', 'doc_0001', 1
 
UNION ALL SELECT 'doc_00010002', 'doc_0001', 2
 
UNION ALL SELECT 'doc_000100010001', 'doc_00010001', 1
 
UNION ALL SELECT 'doc_000100020001', 'doc_00010002', 1
 
UNION ALL SELECT 'doc_0002', null, 2
 
UNION ALL SELECT 'doc_00020001', 'doc_0002', 1
 
UNION ALL SELECT 'doc_00020002', 'doc_0002', 2
 
UNION ALL SELECT 'doc_000200010001', 'doc_00020001', 1
 
UNION ALL SELECT 'doc_000200020001', 'doc_00020002', 1
 
)
, cte(doc_no,parent_doc_no, o_sort, sort)
as
(
select doc_no,parent_doc_no,sort,  CAST( sort AS NVARCHAR(MAX) ) + CAST( SUBSTRING( doc_no, 5, 100) AS NVARCHAR(MAX) )
from t_tree with(nolock)
where parent_doc_no is null
 
union all
 
select a.doc_no, a.parent_doc_no,a.sort, b.sort + CAST( a.sort AS NVARCHAR(MAX) ) + RIGHT( a.doc_no, 4 )
from t_tree a with(nolock), cte b
where a.parent_doc_no = b.doc_no
)
, maxDepth( md )
AS
(
SELECT MAX( LEN( sort ) )
FROM cte
)
 
SELECT doc_no, parent_doc_no, o_sort AS sort
FROM cte
CROSS JOIN maxDepth
ORDER BY LEFT( cte.sort + REPLICATE( '9', md ), md ) DESC
;
우욱님이 2013-09-30 12:25에 작성한 댓글입니다. Edit

감사합니다. 정말 많은 도움이 되었습니다.~

내마음벌집님이 2013-10-08 14:10에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
674464bit SQL Server 로 컨버트 [1]
박아무개
2013-10-10
7099
6743최근 매출액 조회 [4]
초봉이
2013-10-07
7198
6742and 조건 적용이 않되요... [3]
김우성
2013-10-01
7351
6741tree 구조 sorting 관련 질문드립니다. [4]
내아음벌집
2013-09-29
9354
6739두가지 계산식을 쿼리문으로 만들고 싶어요... [2]
김우성
2013-09-28
7671
6738테이블 A에 없는것 찾기와 없는것만 삭제할수 있는 쿼리좀 갈켜주세요... [2]
김우성
2013-09-27
7687
6737MSSQL 에 연결하는 프로그램에서 최적 Connection 개수는 어떻게 판단해야하나요? [1]
고영훈
2013-09-27
7805
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2023 DSN, All rights reserved.
작업시간: 0.051초, 이곳 서비스는
	PostgreSQL v16.1로 자료를 관리합니다