Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
7-Теория_по_языку_MDX.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
603.65 Кб
Скачать

Синтаксис языка mdx

Запрос на языке MDX представляет собой набор команд, который выглядит следующим образом:

SELECT <описание осей куба>

FROM <название куба>

WHERE <описание срезов куба>

Полный SELECT-запрос должен содержать:

  • В одном запросе можно указать до 128 осей,

  • Список членов измерения, которые должны быть включены для каждой

  • оси,

  • Имя куба, к которому производится запрос,

  • Список членов среза.

Модели данных mdx: кортежи и множества Кортежи

Язык MDX оперирует не только с размерностями (Dimensions), но и с кортежами. Кортеж - это комбинация членов из одной или более размерностей, удобная для манипуляций в MDX. Например, простой кортеж, состоящий из членов одной размерности: [YQMD].[1997].

Для составления кортежа, содержащего члены более чем одной размерности, необходимо все члены поместить в круглые скобки: ([Product]. [Beverages], [Customer]. [Brazil]).

Построенные кортежи можно вызывать с помощью запросов, например результатом выполнения запроса: SELECT

{ ([YQMD].[A11 YQMD].[1997], [Measures].[Discounted Total]), ([YQMD].[A11 YQMD].[1997], [Measures].[Line Item Discount]), ([YQMD].[A11 YQMD].[1996], [Measures].[Discounted Total]), ([YQMD].[A11 YQMD].[1996], [Measures].[Line Item Discount])

}

ON COLUMNS,

{[Product].[All Product].[Beverages].[Chai], [ProductUAll Product].[Beverages].[Ipoh Coffee]} ON ROWS

FROM Sales

Будет:

Рис. 1. Операции с использованием кортежей

Примечание: Нельзя использовать пустые кортежи () или использовать в одном кортеже 2 члена одного измерения, например временные ([YQMD].[1996], [YQMD].[1997]).

Множества

Множество - это запрос набора кортежей. Множество может включать в себя более одного кортежа, один кортеж или быть пустым. Кроме того, множество может содержать несколько одинаковых кортежей. В зависимости от контекста, в котором

используется множество, оно означает либо множество кортежей, либо значения в ячейках, определяемые кортежами.

Синтаксически, множество можно определить через набор кортежей, перечислив их в фигурных скобках {}. В качестве примера рассмотрим запрос, по колонкам которого два простых множества, а по рядам — одно:

SELECT

{ ([YQMD].[A11 YQMD].[1997].[1]), ([YQMD].[A11 YQMD].[1997])

}

ON COLUMNS,

{[Product].[All Product].[Meat/Poultry], [Product].[All Product].[Seafood]} ON ROWS

FROM Sales

Результатом выполнения запроса становятся данные по 1 кварталу 1997 года и всему 1997 году о продажах мясных и морских продуктов.

1 Квартал

1997

Meat/Poultry

24 152,30p,

87 648,12р.

Seafood

8 092,60р.

69 780,30р.

Рис. 2. Множества в запросе.

Примечание: Отличия кортежей от множеств по синтаксису:

  • Множество, содержащее кортеж «{([YQMD].[All YQMD].[1997])}»;

  • Кортеж «([YQMD].[All YQMD].[1997])».

Примечание: Множество может быть пустым, например {}.

Изучив модели данных в MDX, можем приступить к более подробному рассмотрению применения MDX в приложении Microsoft SQL Server 2000 Analysis Services.

MDX Sample Application

В Microsoft SQL Server 2000 Analysis Services выберем утилиту MDX Sample Application. При запуске на экране появляется панель Connect, в которой необходимо указать имя сервера (имя компьютера, на котором установлен Microsoft SQL Server 2000 Analysis Services) и тип провайдера для связи с сервером - MSOLAP.

Рис. 3. Панель Connect

После выбора параметров связи можно нажать ОК. Открывшееся приложение содержит панели:

1. выбор базы данных MS SQL Server 2000 (в нашем примере это Northwind_s),

2. выбор куба, созданного в MS SQL Server 2000 Analysis Services, на основе данных таблицы факта БД Northwind_s (Sales).

Рис. 4. Панели инструментов MDX Sample Application

Панель, обозначенная под номером 3 на рис.2 отображает текст mdx-запроса, выбранного на панели Queries справа от панели выбора базы данных, или создаваемого пользователем. По умолчанию, в списке запросов находятся запросы из файла MDXQuery.mdx. Для загрузки другого файла или сохранения текущего используются команды меню File.

Примечание. При построении_МБХ-запроса названия осей можно вводить как

непосредственно с клавиатуры, так и перетаскивать мышью из панели «Измерения

куба» (4 на рис.2). Выполнение запроса осуществляется с помощью команды Run в

11 меню Query, нажатием клавиши F5 или нажатием стрелки «вправо» на панели инструментов.

Результат выполнения запроса отображается в нижней части экрана или, если выбрана

опция View | Results, во весь экран.

Ниже рассмотривается язык MDX применительно к Microsoft SQL Server 2000 Analysis Services.

Все примеры будут выполнены в демонстрационной базе FoodMart 2000, входящей в состав Analysis Services (в ней представлены данные о продажах за 1997 год, все продажи пришлись на территорию США). Будут рассмотрены только MDX-запросы; MDX-выражения будут оставлены вне рамок этой работы.

Простейшие MDX-запросы

Пример 1. Простейший запрос

SELECT FROM Sales

В этом примере мы получили общее количество проданных единиц (Unit Sales) для всего куба. Поскольку в запросе мы не указали имена членов измерений, были выбраны члены по умолчанию для каждого измерения.

Пример 2. Указание в запросе столбцов

SELECT

{[Measures].[Unit Sales]} ON COLUMNS

FROM Sales

Результат аналогичен результату примера 1

Пример З. Указание в запросе строк

SELECT

{[Measures].[Unit Sales]} ON COLUMNS,

{[Time].[1997]} ON ROWS

FROM Sales

Результат аналогичен вышеприведенному.

Пример 4. Указание фильтра в запросе

Определим общее количество проданной продукции за 1997 год только в магазинах на территории США.

SELECT

{[Measures].[Unit Sales]} ON COLUMNS,

{[Time].[1997]} ON ROWS

FROM Sales

WHERE ([Store].[All Stores].[USA])

Примечание. Результаты всех 4 примеров совпали, т.к. в базе находятся результаты только за 1997 и все продажи пришлись на территорию США.

Использование квадратных скобок

Имя необходимо заключать в квадратные скобки, если оно:

  • Содержит пробел или другой специальный символ - [Gross Profit].

  • Совпадает с ключевым словом - [SELECT].

  • Начинается с цифры - [093Setup].

В общем же случае рекомендуется использовать полные имена, заключенные в квадратные скобки - [Store].[All Stores].[Canada].[ВС].[Vancouver].[Store 19]

Использование запятой для разделения наборов элементов

Пример 5. Использование запятой

Определим общее количество проданной продукции, общие затраты и общая выручка за 1997 год в магазинах на территории США.

SELECT

{[Measures].[Unit Sales], [Measures].[Store Cost], [Measures].[Store Sales]} ON COLUMNS,

{[Time].[1997]} ON ROWS

FROM Sales

WHERE ([Store].[All Stores].[USA])

Использование двоеточия для определения диапазона

Пример 6. Использование двоеточия

Напишем запрос для нахождения общего количества проданных единиц с января по август 1997 года

SELECT

{[Measures].[Unit Sales]} ON COLUMNS,

{[Time].[1997].[Ql].[l]:[Time].[1997].[Q3].[8]} ON ROWS

FROM Sales

Использование фигурных скобок для определения набора элементов (sets)

В MDX { } используются для обозначения набора элементов (в том числе именованного). Один набор может быть вложен в другой.

Пример 7. Использование вложенных наборов

SELECT

{[Measures].[Unit Sales]} ON COLUMNS,

{{[Store].[USA].[CA], [Store].[USA].[OR], [Store].[WA]}, [Store].[Canada]} ON ROWS

FROM Sales

Выдается результат по общему количеству продаж в 3 отдельных штатах США и полностью по Канаде.

Использование операторов Children и Members

Пример 8. Использование оператора Children

SELECT

{[Store Type].[All Store Type].Children} ON COLUMNS,

{[Time].[1997].Children} ON ROWS

FROM Sales

WHERE ([Measures].[Store Sales])

Выводится сумма продаж по кварталам 1997 года и по типам магазинов.

Пример 9. Использование оператора Members

SELECT

{[Store Type].Members} ON COLUMNS,

{[Time].Members} ON ROWS

FROM Sales

WHERE ([Measures].[Store Sales])

Выводится сумма продаж по всем значениям измерения Time и Store Type (продажи по всем типам магазинов, а также общий объем продаж и по всем месяцам, кварталам, годам)

Пример 10. Объем продаж в штатах СА и WA в 1 и 2 кварталах 1997 года

SELECT

{[Store].[All Stores].[USA].[CA],[Store].[All Stores].[USA].[WA] } ON COLUMNS,

{[Time].[1997].[ql], [Time].[1997].[q2]} ON ROWS

FROM Sales

Пример 11. Объем продаж морепродуктов, мяса и яиц в штатах С А и WA за все время

SELECT

{[Store].[All Stores].[USA].[CA],[Store].[All Stores].[USA].[WA] } ON COLUMNS, {[Product].[All Products].[Food].[Seafood], [Product].[All Products].[Food].[Meat], [Product].[All Products].[Food].[Eggs] } ON ROWS FROM Sales

Пример 12. Количество сделок и средняя сумма сделки по продуктовой семье за все время

SELECT

{[Measures].[Sales Count], [Measures].[Sales Average] } ON COLUMNS,

{[Product].[Product Family].Members} ON ROWS

FROM Sales

Пример 13. Количество сделок и средняя сумма сделки по продуктовой семье за все время с покупателями-женщинами

SELECT

{[Measures].[Sales Count], [Measures].[Sales Average] } ON COLUMNS,

{[Product].[Product Family].Members} ON ROWS

FROM Sales

WHERE ([Gender].[All Gender].[F])

Пример 14. Количество сделок и средняя сумма сделки по продуктовой семье за все время с покупателями - незамужними женщинами

SELECT

{[Measures].[Sales Count], [Measures].[Sales Average] } ON COLUMNS,

{[Product].[Product Family].Members} ON ROWS

FROM Sales

WHERE ([Gender].[All Gender].[F], [Marital Status].[All Marital Status].[S])

Пример 15. Зависимость количества покупок по продуктовой семье в супермаркетах штата С А от замужества среди женщин в 1 квартале 1997

SELECT

{[Marital Status].Children} ON COLUMNS,

{[Product].[Product Family].Members} ON ROWS

FROM Sales

WHERE ([Measures].[Sales Count], [Gender].[All Gender].[F] ,[Store].[All Stores].[USA].[CA],

[Store Type].[All Store Type].[Supermarket], [Time].[1997].[Ql] )

Таких относительно простых запросов можно написать очень много. Но даже при такой простоте можно получить довольно интересные, а главное полезные для принятия управленческих решений срезы данных.

Использование функции CrossJoin() и оператора *

Функция CrossJoin() используется для пересечения 2 наборов данных. Соответственно, можно делать запросы к нескольким измерениям и размещать их в одной оси.

Пример 16. Использование функции CrossJoin()

SELECT

CROSSJOIN(

{[Customers].[All Customers].[USA]. [CA].[Altadena], [Customers].[All

Customers]. [USA]. [OR]. [Albany]},

{[Product].[Product Family].Members}) on columns,

{[Time].[Year].[1997].Children} on rows

FROM

Sales

WHERE

([Measures].[Store Sales])

Выдается сумма продаж жителям 2 городов (Altadena и Albany) по продуктовой семье с разбивкой по кварталам 1997 года.

Пример 17. Данные по количеству покупок в 1 и 2 кварталах 1997 года по уровню дохода, по штату, по продуктовой семье

SELECT

CROSSJOIN (

{[Time].[1997].[Ql],[Time].[1997].[Q2]},

{[Yearly Income].[Yearly Income].Members}

) on columns,

CROSSJOIN

({[Store].[Store State].members}, {[Product].[Product Family].members})

FROM Sales

WHERE ([Measures].[Sales Count])

Функция CrossJoin() может работать только с 2 измерениями. Но это ограничение можно обойти, используя вложенные функции CrossJoin().

Пример 18. Использование вложенных CrossJoin()

SELECT

CrossJoin(

CrossJoin( {[Customers].[All Customers].[USA].[CA].[Altadena],

[Customers].[All Customers].[USA].[OR].[Albany] },

{ [Product].[Product Family].Members }),

{ [Store].[Store State].[CA], [Store].[Store State].[OR]}) on columns,

{[Time].[Year].[1997].Children} on rows

FROM

Sales

WHERE

([Measures].[Store Sales])

Сумма продаж по кварталам для региона СА и OR жителям городов Altadena и Albany с разбивкой по продуктовой семье.

Оператор * является альтернативой функции CrossJoin() (он также допускает вложения)

Пример 19. Использование *

Аналог примера 17 с использованием *.

SELECT

{{[Time].[1997].[Ql], [Time].[1997].[Q2]} *

{[Yearly Income].[Yearly IncomeJ.Members}}

on columns,

{{[Store].[Store State].members} * {[Product].[Product Family].members}} on rows

FROM Sales

WHERE ([Measures].[Sales Count])

Использование функций Filter(), Order(), TopCount()

Пример 20. Использование Filter()

SELECT

{[Measures].[Sales Count]} on columns,

FILTER({[Product].[Product Name].Members}, ([Measures].[Sales Count], [Time].[Year].[1997]) >75 ) on rows

FROM Sales

i

Отображаются только продукты, по которым за 1997 год было более 75 сделок.

Пример 21. Не показывать пустые ячейки

Отображаются только те семейства продуктов, по которым за 1 квартал 1997 года было не более 888 сделок с гражданами, чей доход находится в промежутке 10-30.

SELECT NON EMPTY {{[Time].[1997].[Ql], [Time].[1997].[Q2]} * {[Yearly Income].[Yearly Income].Members}} on columns,

NON EMPTY FILTER ({{[Store].[Store State].members} * {[Product].[Product Family].members}}, ([Measures].[Sales Count],[Time].[1997].[Ql], [Yearly Income].[All Yearly Income].[$10K - $30K]) <=888 ) on rows

FROM Sales

WHERE ([Measures].[Sales Count])

Пример 22. Использование сортировки Order().

SELECT

{[Measures].[Sales Count]} on columns,

ORDER(

{[Product].[Product Name].Members }, ([Measures].[Sales Count]), BASC ) on rows

FROM Sales

Отображаются продукты в порядке возрастания сделок в 1997.

Пример 23. Совместное использование Order() и Filter().

SELECT

{[Measures].[Sales Count]} on columns,

ORDER(

FILTER(

{[Product].[Product Name].Members}, ([Measures].[Sales Count], [Time].[Year].[1997]) >75 ),

([Measures].[Sales Count], [Time].[Year].[1997]), BDESC) on rows

FROM Sales

Отображаются в порядке убывания продукты, по которым за 1997 год было более 75 сделок.

Пример 24. Использование TopCount()

SELECT

{[Measures].[Sales Count]} on columns,

TOPCOUNT([Product].[Product Name].Members, 5, [Measures].[Sales Count])

on rows

FROM Sales

Отображается пятерка продуктов, по которым было большинство сделок

Пример 25. Совместное использование NonEmpty и TopCount

Определим самый продаваемый товар в каждом штате.

SELECT

{[Measures].[Sales Count]} on columns,

NONEMPTY {{[Store].[Store State].members} * TOPCOUNT({[Product].[Product Name].members},1, [Measures].[Sales Count])} on rows FROM Sales

Использование агрегатных функций

Пример 26. Использование вычислений

Просмотр прибыльности по кварталам 1997

WITH

MEMBER [Measures].[Profitability] AS

'100*[Measures].[Store Sales Net]/[Measures].[Store Sales]'

SELECT

{[Measures].[Store Sales Net], [Measures].[Store Sales], [Measures].[Profitability] } on columns,

{[Time].[ 1997] .Children} on rows

From Sales

Пример 27. Использование функции AVG

Определим среднюю стоимость продаж по кварталам.

WITH

MEMBER [Measures].[TestAVG] AS

AVG(Product.[Product Name].members,[Measures].[Store Sales])'

SELECT

{ [Measures].[Store Sales], [Measures].[TestAVG] } on columns,

{[Time].[1997].Children} on rows

From Sales

Пример 28. Вычисление тренда

WITH

Member Measures.X AS

'Rank(Time, [Time]. [Month] .Members)'

Member Measures.Trend AS 'LinRegPoint(X, [Time].[Month].Members,[Store Sales], x)'

SELECT

{[Store Sales], X, Trend} ON COLUMNS,

[Time].[Month].Members ON ROWS

FROM SALES

Пример 29. Функция проверки условия

WITH MEMBER [Measures].[Diff] AS

'IIF (([Store Cost] > [Store Sales]),([Measures].[Store Cost]-[Measures].[Store Sales Net]),

([Measures].[Store Sales Net]-[Measures].[Store Cost]))'

SELECT

{[Measures].[Store Sales Net],[Measures].[Store Cost], [Measures].[Diff]} on columns,

{[Gender]. [Gender] .members } on rows

from Sales

Функции форматирования

Пример 30. Вычисление процента

Вычислим процент с 2 знаками после запятой.

WITH member [Measures].[Store Profit Rate] as '([Measures].[Store Sales]-[Measures].[Store Cost])/ [Measures].[Store Cost]', format = '#.00%'

SELECT

{[Measures].[Store Cost],[Measures].[Store Sales], [Measures].[Store Profit Rate]} on columns, Order( [Product]. [Product Department] .members, [Measures].[Store Profit Rate], BDESC) on rows

FROM Sales