MDX 활용
안녕하세요 강성욱 입니다.(www.sqltag.org, www.sqler.com, http://sqlmvp.kr)
이번 시간에는 MDX 활용에 대해서 알아 보도록 하겠습니다.
MDX – Multidimensional Expressions는 관계형 데이터베이스의 SQL에 해당.
다차원 큐브 공간은 해당 큐브를 구성하는 차원들에 의하여 구조가 결정됩니다. 큐브를 구성하는 차원들의 교차점에는 셀이라고 하는 단위 공간이 위치하며 분석의 대상이 되는 측정값이 들어 있습니다.
큐브 공간 임의의 위치에 있는 측정값들을 참조하려면 우선 해당 셀들의 주소를 알아야 합니다. 튜블(Tuple)은 다차원 큐브 공간의 주소를 나타내는 좌표를 의합니다.
기하학의 경우 2차원 공간에서는 (X, Y)와 같은 형태로 3차원의 공간은 (X, Y, Z)와 같은 형태로 좌표를 나타냅니다. N차원의 큐브로 확장이 가능하며 기하학에서의 좌표와 다른점은 기하학에서는 X, Y의 순서에 따라 서로 다른 위치를 참조 하지만 튜블의 경우에는 순서에 상관없이 모두 동일한 좌표를 가리킵니다. 이는 어떠한 멤버를 지정할 때 그 멤버가 속한 차원까지 함께 결정이 되기 때문입니다.
[특정 멤버의 전체 대비 비율 계산]
가장 많이 사용하는 계산중 하나가 전체 대비 비율계산입니다. 제품 전체 판매액 대비 특정 제품이 차지하는 판매 기여도를 보고 싶을 때 튜플을 이용하여면 이러한 요구를 쉽게 해결할 수 있습니다.
예를들어 양주(Alcohol)가 제품 전체에서 차지하는 판매 기여도를 구해 보겠습니다. 요구사항은 (양주 판매액) / (제품 전체 판매액)이 됩니다. 이제 큐브내에서 분자, 분모에 해당하는 좌표를 찾아서 참조하면 됩니다. 구체적으로 표현하면 (판매액, 양주) / (판매액, 제품 전체)가 됩니다. 튜플들을 각 차원 멤버들을 이용하여 기술하면 다음과 같이 정의 됩니다.
([Sales Amount], [Alcohol]) / ([Sales Amount], [AllProducts]) |
큐브 또는 차원에서 멤버 자신만으로 유일성을 보장하지 못하면 최소한 유일성을 보장하는 조상 멤버들을 포함하여 기술해야 하며 필요한 경우 차원(또는 계층 구조)까지 포함하여 기술 하기도 합니다.
([Measures].[Sales Amount], [Product].[[ProductCategories].[Alcohol]) / ([Sales Amount], [AllProducts]) |
[임의 멤버의 전체 대비 비율 계산]
전체 대비 비율 계산은 항상 제품 전체에 대한 품목 제품군의 매출기여도를 계산합니다. 왜냐하면 분자와 분모 모두 특정 셀만을 참조하도록 명시되었기 때문입니다. 그렇지만 많은 경우 제품 전체에 대하여 현재 참조하고 있는 제품 멤버들의 매출 기여도를 보고 싶어 합니다. 이런 경우 분자가 자동으로 현재 제품 멤버를 참조하도록 변경되어야 합니다.
(판매액, 현재 제품 멤버) / (판매액, 제품 전체의 판매액)
([Sales Amount], [Product].[Product Categories], CurrentMember) / (Sales Amount], [All Products]) |
튜플에서 기술하지 않는 차원은 해당 차원의 현재 멤버를 자동으로 참조 합니다. 따라서 다음과 같이 단순화 시킬 수 있습니다.
([Sales Amount]) / ([Sales Amount], [All Products]) |
두개 이상의 차원으로 확장하여 쿼리를 작성할 수도 있습니다.
([Sales Amount]) / ([Sales Amount], [All Products], [All Customers]) |
[부모 대비 비율 계산]
현재 보고 있는 제품 멤버의 부모 멤버에 대한 매출 기여도 입니다. (매출액, 현재 제품 멤버) / (매출액, 현재 제품 멤버의 부모 멤버)가 됩니다.
([Sales Amount], [Product].[Product Categories].CurrentMember) / ([Sales Amount], [Product].[Product Categories].CurrentMember.Parent) |
위의 쿼리를 단순화 시킬 수 있습니다.
([Sales Amount]) / ([Sales Amount], [Product].[Product Categories].Parent) |
현재 멤버가 [All Product]인 경우는 부모 멤버가 존재하지 않기 때문에 분모가 NULL이 됩니다. 이 때 NULL은 0으로 치환 됨으로 [1.#NF]와 같은 오류 값이 반환됩니다. 따라서 필요에 따라 다음처럼 조건부 처리를 해야 합니다.
IIF(IsEmpty(([Sales Amount], [Product].[Product Categories].Parent)), 1, ([Sales Amount]) / ([Sales Amount], [Product].[Product Categories].Parent)) |
강성욱 / jevida@naver.com
Microsoft SQL Server MVP
Blog : http://sqlmvp.kr
Facebook : http://facebook.com/sqlmvp