재귀 쿼리에서 계층 구조를 주문하면 SQL 2005가 있습니다
-
22-08-2019 - |
문제
다음 열이있는 '작업'테이블이 있습니다 (Taskorder는 전체 테이블이 아닌 부모의 범위 내에서 어린이를 주문하기위한 것입니다).
TaskId ParentTaskId TaskName TaskOrder
이 CTE 쿼리가 모든 행을 반환 할 수 있습니다.
with tasks (TaskId, ParentTaskId, [Name]) as
(
select parentTasks.TaskId,
parentTasks.ParentTaskId,
parentTasks.[Name]
from Task parentTasks
where ParentTaskId is null
union all
select childTasks.TaskId,
childTasks.ParentTaskId,
childTasks.[Name]
from Task childTasks
join tasks
on childTasks.ParentTaskId = tasks.TaskId
)
select * from tasks
이 쿼리는 예상대로 레벨별로 주문한 모든 작업을 반환합니다. 아래와 같이 결과를 계층 구조 순서로 주문하도록 어떻게 변경하려면?
- Task 1 -- Task 1 Subtask 1 -- Task 1 Subtask 2 - Task 2 - Task 3
감사.
편집하다: 답은 무제한 수준의 레벨과 함께 작동해야합니다.
해결책 2
변형을 사용하여 문제를 해결했습니다 마크의 방법, 그러나 나는 모든 노드에서 노드 경로를 유지하지 않으므로 나무 주위를 더 쉽게 움직일 수 있습니다. 대신 나는 내 'Orderby'열을 int에서 varchar (3)로 0으로 왼쪽으로 0으로 변경하여 반환 된 모든 행에 대해 마스터 '주문'으로 연결할 수 있습니다.
with tasks (TaskId, ParentTaskId, OrderBy, [Name], RowOrder) as
(
select parentTasks.TaskId,
parentTasks.ParentTaskId,
parentTasks.OrderBy,
parentTasks.[Name],
cast(parentTasks.OrderBy as varchar(30)) 'RowOrder'
from Task parentTasks
where ParentTaskId is null
union all
select childTasks.TaskId,
childTasks.ParentTaskId,
childTasks.OrderBy,
childTasks.[Name],
cast(tasks.RowOrder + childTasks.OrderBy as varchar(30)) 'RowOrder'
from Task childTasks
join tasks
on childTasks.ParentTaskId = tasks.TaskId
)
select * from tasks order by RowOrder
이것은 반환됩니다 :
TaskId ParentTaskId OrderBy Name RowOrder --------------------------------------------------------------------------- 1 NULL 001 Task One 001 15 1 001 Task One / Task One 001001 2 NULL 002 Task Two 002 7 2 001 Task Two / Task One 002001 14 7 001 Task Two / Task One / Task One 002001001 8 2 002 Task Two / Task Two 002002 9 8 001 Task Two / Task Two / Task One 002002001 10 8 002 Task Two / Task Two / Task Two 002002002 11 8 003 Task Two / Task Two / Task Three 002002003 3 NULL 003 Task Three 003 4 NULL 004 Task Four 004 13 4 001 Task Four / Task One 004001 5 NULL 005 Task Five 005 6 NULL 006 Task Six 006 17 NULL 007 Task Seven 007 18 NULL 008 Task Eight 008 19 NULL 009 Task Nine 009 21 19 001 Task Nine / Task One 009001 20 NULL 010 Task Ten 010
무제한 계층 구조 (부모 노드 당 최대 10 레벨 / 최대 1000 명의 어린이 - 0시에 주문을 시작한 경우)를 허용하지는 않지만 내 필요에 따라 충분합니다.
다른 팁
이를 수행 할 수있는 한 가지 방법은 목록에 이전 ID가있는 계층 구조 열을 추가하는 것입니다.
with tasks (TaskId, ParentTaskId, [Name], TaskIdList) as
(
select parentTasks.TaskId,
parentTasks.ParentTaskId,
parentTasks.[Name],
parentTasks.TaskId
from Task parentTasks
where ParentTaskId is null
union all
select childTasks.TaskId,
childTasks.ParentTaskId,
childTasks.[Name],
tasks.TaskIdList + '.' + childTasks.TaskId
from Task childTasks
join tasks
on childTasks.ParentTaskId = tasks.TaskId
)
select TaskId, ParentTaskId, [Name] from tasks
order by TaskIdList
이것은 taskID가 문자열 기반 ID라고 가정합니다. 그렇지 않다면, 당신은 그것을 연결하기 전에 Varchar에 캐스팅해야합니다.
당신은 모든 연합 물건이 필요하지 않습니다. 나는 이것이 효과가 있다고 생각합니다.
select
TaskId,
ParentTaskId,
[Name],
COALESCE(ParentTaskId, TaskId) as groupField
from
task
order by
COALESCE(ParentTaskId, TaskId), ParentTaskId, TaskId
"주문"을 지정하지 않기 때문에 쿼리 분석기가 예상되는 방식으로 작동하기를 희망하는 것 외에는 특정 주문으로 반환 할 것으로 예상합니까?
ParentTaskId, taskId 순서로 원한다면 첫 번째 Union 요소에서 taskID를 ParentTaskID로 선택하고 NULL을 선택하십시오. 그 다음에
ParenttAskid, taskId에 의해 주문?