2012-09-26 4 views
0

이것은 어리석은 것처럼 보일지 모르지만 한 번에이 쿼리를 해결하려고합니다.XML을 사용하여 재귀 적으로 쿼리 할 수 ​​있습니까?

SQL 데이터베이스에 자체적으로 다시 연결되는 테이블이 있습니다. 조직 ID와 상위 조직 ID가 있습니다. 최상위 조직의 상위 ID는 0이며 다른 수준의 각 조직에는 상위 조직 중 하나의 상위 조직이 있습니다. org 수준이라는 테이블의 다른 필드에 의해 결정되는 데 사용 된 조직의 수준입니다. 그러나 이제 레벨은 트리가 org보다 얼마나 떨어져 있는지에 따라 결정됩니다. 예를 들어 org가 다른 부모를 가진 부모를 가지고 있다면 첫 번째 조직은 레벨 3에, 부모는 레벨 2에 있고 조부모는 레벨 1에 있습니다.

SQL을 어떻게 작동시키는 지 알고 있습니다. 문제는 나에게 org와 그 레벨을 돌려주는 일반적인 SQL 문을 만드는 것이다. XML을 사용하여이 작업을 수행하기로 결정했지만 이것이 최선의 방법은 아닙니다. 이런 조직 구조를 가지고 있다고 가정 해 봅시다. 나는 내가 조회하는 방법을 많은 수준 알고있는 경우에 나는 일반적으로이 작업을 수행하는 방법을 알아 낸

<Organizations> 
    <Lvl1 OrgID="1" Name="Top Level 1" Index="1"> 
    <Lvl2 OrgID="5" Name="Second Level 1" Index="1" /> 
    <Lvl2 OrgID="6" Name="Second Level 2" Index="2" /> 
    </Lvl1> 
    <Lvl1 OrgID="3" Name="Top Level 2" Index="2"> 
    <Lvl2 OrgID="7" Name="Second Level 3" Index="1" /> 
    <Lvl2 OrgID="8" Name="Second Level 4" Index="2" /> 
    </Lvl1> 
    <Lvl1 OrgID="4" Name="Top Level 3" Index="3"> 
    <Lvl2 OrgID="9" Name="Second Level 5" Index="1" /> 
    <Lvl2 OrgID="10" Name="Second Level 6" Index="2" /> 
    </Lvl1> 
</Organizations> 

: 완료되면

-Top Org 1 
--Second Org 1 
--Second Org 2 
-Top Org 2 
--Second Org 3 
--Second Org 4 
-Top Org 3 
--Second Org 5 
--Second Org 6 

는,이처럼 보이는 XML을 조회 할 에 대한.

SELECT 
    Lvl1.Org_ID [@OrgID] 
    ,Lvl1.Org_Name [@Name] 
    ,Lvl1.Org_SortID [@Index] 
    ,(
     SELECT 
      Lvl2.Org_ID [@OrgID] 
      ,Lvl2.Org_Name [@Name] 
      ,Lvl2.Org_SortID [@Index] 
     FROM Organizations Lvl2 
     WHERE Lvl2.Org_ParentID = Lvl1.Org_ID 
     GROUP BY Lvl2.Org_ID, Lvl2.Org_Name, Lvl2.Org_SortID 
     ORDER BY Lvl2.Org_SortID 
     FOR XML PATH('Lvl2'), TYPE 
    ) 
FROM Organizations Lvl1 
INNER JOIN Organizations Child1 ON Lvl1.Org_ID = Child1.Org_ParentID 
WHERE Lvl1.Org_ParentID = 0 
GROUP BY Lvl1.Org_ID, Lvl1.Org_Name, Lvl1.Org_SortID 
ORDER BY Lvl1.Org_SortID 
FOR XML PATH('Lvl1'), ROOT('Organizations')

을하지만 이제 내가 가질거야 얼마나 많은 수준 모르는 척하자 : 나는 제 1 및 제 2 수준을 조회 할 경우에, 나는이 작업을 수행. 나는 두 단계 밖에 가질 수 없으며, 나는 15 단계를 가질 수도 있습니다. 그리고 모든 조직이 동일한 수의 레벨을 가질 수는 없습니다. 제가 찾고자하는 것은 그것이 들어올 때 각 레코드를 재귀 적으로 살펴보고 그 아래에 자식이 있는지 여부를 판단 할 수있는 방법이 있는지입니다. 그렇다면 어린이들을위한 새로운 XML 태그를 작성하고 한 단계 아래로 드릴 다운 한 다음 각 자녀를 확인하고 자녀가 있는지 확인하십시오. Ect.

이 작업을 수행하는 좋은 방법이 아닐 수도 있고, SQL을 만들기 위해 거대한 메모리와 시간 싱크가 될 수도 있습니다. 그러나 그렇지 않다면 가능한 일임을 알리고 사례를 보여주십시오. 감사!

+0

- SQL에서 처리 나무와 다른 그래프가 큰 이론과 실제 문학의 주제입니다; 몇 가지 지침은 http://stackoverflow.com/questions/4048151/what-are-the-options-for-storing-hierarchical-data-in-a-relational-database를 참조하십시오. XML 측면에서 - 어떤 조직이 하위 조직을 가질 수있는 경우, 트리의 다른 레벨에서 요소에 다른 이름을 부여해야하는 이유는 무엇입니까? * Lvl1 * 및 Lvl2 * 및 Lvl15 * 중 일부를 호출하는 대신 각 노드 * 조직 *을 호출하는 것이 더 간단합니다. –

답변

1

나는 재귀 함수 (즉, 자체 호출)를 사용하여 해결 한 유사한 문제가 최근에 발생했습니다.

내가 테스트를하지 않은 그러나이 같은 일을해야

:

는 SQL 측면에서
CREATE FUNCTION dbo.GetChildOrganisations (@ParentID INT) 
RETURNS XML 
AS 
BEGIN 
    RETURN 
    ( SELECT Org_ID [@OrgID], 
       Org_Name [@Name], 
       Org_SortID [@Index], 
       dbo.GetChildOrganisations(Org_ID) [ChildOrganisations] 
     FROM Organizations 
     WHERE Org_ParentID = @ParentID 
     FOR XML PATH('Orgainisations') 
    ) 
END 
관련 문제