powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Хитрые (Неаддитивные) Calculated Member
12 сообщений из 12, страница 1 из 1
Хитрые (Неаддитивные) Calculated Member
    #32572831
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решается проблема DistinctCount c помощью CalculatedMembers, см. Запрос.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
WITH 

SET [CustomerMembers] AS '{[Customer].[All].[BAUMUE],[Customer].[All].[DIVREN]}'
MEMBER [Customer].Slicer AS 'AGGREGATE([CustomerMembers])'

SET [RowSet0] AS '{
	[ProductGroup].[All].[SAN].[KERAMIK],
	[ProductGroup].[All].[SAN].[ABLA],
	[ProductGroup].[All].[SAN].[SKAN],
	[ProductGroup].[All].[SAN].[FITT]
}'

SET [RowSet1] AS 'NonEmptyCrossjoin([RowSet0],{[Measures].[Relation_Artikel]}, 1)'
SET [RowSet2] AS 'topcount([RowSet1],100,([Time].[All].[2003],[Measures].[Verkaufswert]))'
SET [TotalSet] AS '[RowSet2]'

MEMBER [Measures].[OrderCount] as '
IIF([ProductGroup].CURRENTMEMBER.UNIQUENAME <> "[ProductGroup].[Total]", 
count(NonEmptyCrossJoin([Order].[Order].members, {[ProductGroup].CURRENTMEMBER}, {[CustomerMembers]},1)),
count(NonEmptyCrossJoin([Order].[Order].members, {[RowSet1]}, {[CustomerMembers]}, 1))
)'


 -- если бы был выбран только один Customer, то используем физическую меру DistinctCount
 
 -- и не тратимся на дополнитеные расчеты.
 
MEMBER [Measures].[OrderCount] as '
IIF([ProductGroup].CURRENTMEMBER.UNIQUENAME <> "[ProductGroup].[Total]", 
[Measures].[OrderCountPhysic],
count(NonEmptyCrossJoin([Order].[Order].members, {[RowSet1]}, {[CustomerMembers]}, 1))
)' 

MEMBER [ProductGroup].[Total] as 'SUM([RowSet1],[Measures].CurrentMember)'

SELECT 
{
[Time].[All].[ 2004 ],
[Time].[All].[ 2003 ],
[Time].[All].[ 2002 ]
} ON COLUMNS,

CROSSJOIN(
{[ProductGroup].[Total],[RowSet2]},
{[Measures].[SaleValue],[Measures].[PositionCount], [Measures].[OrderCount]})

ON ROWS
FROM Sales
WHERE ([Customer].Slicer)

ибо использование DistinctCount как физической дает неверный результат
при расчете произвольных Totals и при Использовании в Where нескольких элементов в одном измерении (оба случая приведены в примере).

Вопрос.

Как можно, и можно ли вообще, оперируя средствами MDX, создать Calculated Member на стороне сервера, чтобы не заниматься генерацией MDX кода в своем приложении.

Хотя подозреваю, что используя "контекстно завистмую" генерацию MDX запросов можно добиться лучшей производительности нежели если написать "супер сложный" Calculated Member на сервере.


Очень бы хотелось услышать ваши соображения и здоровую критику.
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32572833
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так правильнее.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
WITH 

SET [CustomerMembers] AS '{[Customer].[All].[BAUMUE],[Customer].[All].[DIVREN]}'
MEMBER [Customer].Slicer AS 'AGGREGATE([CustomerMembers])'

SET [RowSet0] AS '{
	[ProductGroup].[All].[SAN].[KERAMIK],
	[ProductGroup].[All].[SAN].[ABLA],
	[ProductGroup].[All].[SAN].[SKAN],
	[ProductGroup].[All].[SAN].[FITT]
}'

SET [RowSet1] AS 'NonEmptyCrossjoin([RowSet0],{[Measures].[Relation_Product]}, 1)'
SET [RowSet2] AS 'topcount([RowSet1],100,([Time].[All].[2003],[Measures].[SaleValue]))'
SET [TotalSet] AS '[RowSet2]'

MEMBER [Measures].[OrderCount] as '
IIF([ProductGroup].CURRENTMEMBER.UNIQUENAME <> "[ProductGroup].[Total]", 
count(NonEmptyCrossJoin([Order].[Order].members, {[ProductGroup].CURRENTMEMBER}, {[CustomerMembers]},1)),
count(NonEmptyCrossJoin([Order].[Order].members, {[RowSet1]}, {[CustomerMembers]}, 1))
)'


 -- если бы был выбран только один Customer, то используем физическую меру DistinctCount
 
 -- и не тратимся на дополнитеные расчеты.
 
MEMBER [Measures].[OrderCount] as '
IIF([ProductGroup].CURRENTMEMBER.UNIQUENAME <> "[ProductGroup].[Total]", 
[Measures].[OrderCountPhysic],
count(NonEmptyCrossJoin([Order].[Order].members, {[RowSet1]}, 1))
)' 

MEMBER [ProductGroup].[Total] as 'SUM([RowSet1],[Measures].CurrentMember)'

SELECT 
{
[Time].[All].[ 2004 ],
[Time].[All].[ 2003 ],
[Time].[All].[ 2002 ]
} ON COLUMNS,

CROSSJOIN(
{[ProductGroup].[Total],[RowSet2]},
{[Measures].[SaleValue],[Measures].[PositionCount], [Measures].[OrderCount]})

ON ROWS
FROM Sales
WHERE ([Customer].Slicer)
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32575901
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Неужели никто с подобной проблемой не сталкивался?
Или проблема на столько банальна, что и говорить о ней не стоит?
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32808523
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
backfireНеужели никто с подобной проблемой не сталкивался?
Или проблема на столько банальна, что и говорить о ней не стоит?

Неужели никто с подобной проблемой не сталкивался?
Или проблема на столько банальна, что и говорить о ней не стоит?
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32808825
Фотография Валек
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
честно скажу не сталкивался
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32809356
Dmitry Biryukov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Честно скажу, не до конца понял вопрос, но я для себя решил проблему DC с фильтром по нескольким элементам так (написал после прочтения одной статьи в инете):
Код: plaintext
count(crossjoin({population},descendants(city.currentmember,city.[city name])),excludeempty)
здесь population-мера
city - измерение
[city name] - нижний уровень этого измерения
Клиент - эксель и OWC. считает на ура!
Например:
RegionAreadistinct Cities countRegion 1Area 127Area 21Area 318Area 424Area 52Area 639Total107
конструктивная критика тоже есть:
вместо
Код: plaintext
[ProductGroup].CURRENTMEMBER.UNIQUENAME <> "[ProductGroup].[Total]"
надо писать
Код: plaintext
NOT [ProductGroup].CURRENTMEMBER IS [ProductGroup].[Total]
© - Моша
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32809432
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и у меня примерно так же:
Код: plaintext
IIF(IsEmpty([Фактов]), null, Count({[Точка].Children} * {[Фактов]}, ExcludeEmpty))
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32809507
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. если PositionCount это у вас сумма позиций в заказе,
определяете в кубе CM OrderCount cо след параметрами:

Код: plaintext
1.
2.
Parent Dimension:   Measures
Non Empty Behavior: PositionCount
Value:              IIF(IsEmpty([PositionCount]), null, Count({[Order].Children} * {[PositionCount]}, ExcludeEmpty))
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32810271
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorт.е. если PositionCount это у вас сумма позиций в заказе,
определяете в кубе CM OrderCount cо след параметрами:

Код: plaintext
1.
2.
Parent Dimension:   Measures
Non Empty Behavior: PositionCount
Value:              IIF(IsEmpty([PositionCount]), null, Count({[Order].Children} * {[PositionCount]}, ExcludeEmpty))



С точки зрения правильности - претензий нет, но с точки зрения производительности ваша формула не использует возможности считать это более коротким путем, если этот путь возможен. А в 90% случаев, можно использовать более короткий, с точки зрения потребных вычислений, путь. Это я собственно и пытался сделать в своем MDX.
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32810888
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эта формула универсальна и не зависит от конкретного запроса.
К тому же в самом вопрсе спрашивалось "как создать CM на стороне сервера?" и предусмотреть все возможные варианты в этом случае не представляется возможным. Даже если все-таки это сделать, удар по производительности будет тем больше, чем больше будет операций выяснения по какой формуле вычислять CM. И более того, любое изменение в структуре куба приведет к необходимости проводить ревизию всех подобных CM.
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32812077
Владимир Штепа
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgorЭта формула универсальна и не зависит от конкретного запроса

Эта формула не универсальна и зависит и от конкретного запроса и от дизайна измерения Order.

- если измерение Order не плоское
- если в WHERE стоит один или несколь членов измерения Order (опосредовано через AGGREGATE и CM)

в этих случаях ваш CM дает неверный результат.
...
Рейтинг: 0 / 0
Хитрые (Неаддитивные) Calculated Member
    #32812317
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
согласен.
но это рассматриваемый в вопросе случай?...
измерение Order не плоское?...
или его члены прямо или опосредовано используются во WHERE?...

был поставлен вопрос - на него был дан ответ! поэтому для этого случая формула универсальна. чего еще?
к тому же замечу, что в формуле от Dmitry Biryukov как раз используется формула для неплоского измерения "Descendants...."
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Хитрые (Неаддитивные) Calculated Member
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]