Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Сложный CM / 16 сообщений из 16, страница 1 из 1
26.05.2006, 12:36
    #33753857
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
Добрый день!

AS2k sp3

Думаю, следует начать описание задачи со структуры данных, служащих основой для таблицы фактов куба. Вот, та часть, которая понадобится:

Код: plaintext
Дата       Оплатить до           Сумма отгрузки         Сумма опаты       Ид

Дальше получился куб, с мерами Сумма отгрузки и Сумма опаты и измерением Дата (упрощенно).
Нужно посчитать сумму просроки на конец периода. Это сумма разности мер
(Сумма отгрузки - Сумма опаты) за выбранный период. Сумма считается только по строкам, у которых поле "Оплатить до" меньше поля "Дата".
...
Рейтинг: 0 / 0
26.05.2006, 12:41
    #33753883
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
Простите за неточность. Не меньше поля "Дата" конечно, а меньше последнего дня выбранного члена измерения "Время", т.е. меньше конца выбранного периода.
...
Рейтинг: 0 / 0
26.05.2006, 12:56
    #33753970
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
Выскажу свои соображения. Поскольку строки агрегируются, вытащить их поле "Оплатить до", чтобы сравнить с концом периода в первозданном виде невозможно. Агрегировать его тоже нельзя :)
Мне поможет измерение, которое сможет "достать" каждую строку по отдельности. Именно поэтому было введено поле "Ид" - уникальный идентификатор записи. По нему было построено виртуальное измерение RecId, в качестве листьев соержащее все идентификаторы строк.
Дальше нужно было перебрать с помощью этого измерения все строки, сравнить даты и получить сумму разностей. Для перебора строк воспользовался функцией Generate, в надежде на конструкцию Current, но видимо я что-то пишу не так, СМ выдает ошибку на выходе.

Код: plaintext
1.
sum(Filter(NonEmptyCrossJoin({[Measures].[Сумма отгрузки]}-{[Measures].[Сумма опаты]}, generate([RecId].CurrentMember.Children as RecIdSet, {[RecId].CurrentMember})),
(RecIdSet.current, [Measures].[Оплатить до]) >  38807 ))

38807 - это я пока для простоты, еще не думал как буду вытаскивать конец периода. Значения поля "Оплатить до" хранятся как int - число дней от 01.01.1900. Это поле я тоже внес в куб как меру.
...
Рейтинг: 0 / 0
26.05.2006, 13:00
    #33753986
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
пардон еще раз, что-то туплю седня крепко (надо было меньше вчера пить)
Не виртуальное измерение RecId, а частное.
пробовал, кстати, и так
Код: plaintext
(RecIdSet.current.item( 0 ), [Measures].[DueDateNum]) >  38807 
...
Рейтинг: 0 / 0
26.05.2006, 13:13
    #33754070
ShIgor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
не вдаваясь в подробности самой задачи, с лету, так сказать..
что Вы хотели получить вот от этой конструкции:
Код: plaintext
NonEmptyCrossJoin({[Measures].[Сумма отгрузки]}-{[Measures].[Сумма опаты]}, ...
оператор "-" между сетами равен функции Extract, т.е.
Код: plaintext
Extract({[Measures].[Сумма отгрузки]}, {[Measures].[Сумма опаты]})

которая вернет Вам сет {[Measures].[Сумма отгрузки]}
...
Рейтинг: 0 / 0
26.05.2006, 13:20
    #33754110
ShIgor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
далее, опять же не влезая сильно в Вашу проблему, а только переделать Ваш CM. Он должен выглядеть примерно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
Sum(
  Filter(
    [RecId].Children,
    [Measures].[Оплатить до] >  38807 
  ),
  [Measures].[Сумма отгрузки] - [Measures].[Сумма опаты]
)

а если вдаваться в проблему, то Вам грозит полный передизайн.
...
Рейтинг: 0 / 0
26.05.2006, 13:23
    #33754127
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
ну плохо я знаю mdx, плохо.. все приходится пробовать методом тыка. а как надо?
при тестировании конечно все равно бы понял, что не считает разность, написал бы как-нибудь по другому, благодоря вам сделаю это раньше :) Задачу это не решает в любом случае
...
Рейтинг: 0 / 0
26.05.2006, 13:26
    #33754140
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
можно вдаваться, передизайн так передизайн, куб все равно еще не эксплуатируется, а в стадии разработки так сказать, так что я могу себе это позволить :)
...
Рейтинг: 0 / 0
26.05.2006, 13:48
    #33754247
ShIgor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
можно, к сожалению сейчас занят, чтобы глубоко влезать еще и в эту задачу.
...
Рейтинг: 0 / 0
26.05.2006, 15:50
    #33754694
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
хм.. похоже уже и не придется никуда влазить, т.к. предложенный код дал то, что было нужно. За что мерси =)
...
Рейтинг: 0 / 0
26.05.2006, 16:30
    #33754870
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
2 ShIgor
а вот еще какой вопрос, вы большой спец по мультиселекту, скажите, можно ли получить последнюю дату в интервале (тот самый конец периода) при мультиселекте?

Я написал такой запросик:
Код: plaintext
Tail(Filter(Descendants([multiTime].[Все даты], [multiTime].[День]), /*not IsEmpty(*/[Measures].[Сумма отгрузки]<> 0 ),  1 ).item( 0 ).item( 0 )

isEmpty почему-то не сработал, хотя данных там нет. А в целом запрос дает то, что нужно, но только при условии, что на протяжении всего выбранного периода будет мера [Measures].[Сумма отгрузки]. А в суровой действительности, меры по всему периоду может и не быть, т.е. факты к примеру могут закончиться 15-го мая, а пользователь выберет март, май. И хотелось бы получить именно 31 мая, а не 15.
...
Рейтинг: 0 / 0
26.05.2006, 17:31
    #33755122
ShIgor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
К сожалению я не знаю структуры вашей базы и исходных данных, но одно ясно: измерение multitime в этом случае должно быть построено без привязки к фактам, т.к. сами сказали, что факт может отсутствовать, а дата должна быть. Однако даже в таком случае я затрудняюсь что-либо предложить.
Вся проблема в том, что мультиселект это не сет, это агрегат. Если, например из Вашего примера, я еще представляю каким способом можно получить 31 мая, то как получить его же, но при отсутствии в мае фактов вообще - это загадка. Сорри...
...
Рейтинг: 0 / 0
26.05.2006, 17:57
    #33755209
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
да.. вероятно без фактов и в самом деле не обойтись, но их и вправду может не быть в последний день периода. Ладно, буду объяснять, что с мультиселектом придется распрощатся..
...
Рейтинг: 0 / 0
27.05.2006, 02:37
    #33755710
OldNov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
зачем так усложнять то, господа? Все намного проще.

Делаем еще один показатель (либо поле в таблицу фактов добавляем, либо просто view модифицируем). Суть поля такая:

newfield = datediff(d, оплатить до, дата оплаты).

С помощью этого поля мы легко отфильтруем все строки с задолженностью (где newfield < 0).

Далее видится два варианта:
1. В кубе делаете CM, суть которого
Measure.[задолженность] = IIF(newfield < 0, сумма оплаты, 0). Автоматически получаем задолженность за месяц (квартал, год) без всяких сумм, tail и прочего неприятного времяпрепровождения.

2. Делаем то же самое в базе - добавляем еще одно поле [задолженность] по формуле, описанной в п1. После этого в кубе просто считаем сумму задолженности, суммируя поле [задолженность] из базы.

Сугубо IMHO мои варианты проще в разы и быстрее. И никакого передизайна не требуется, и MDX тоже не нужен.
...
Рейтинг: 0 / 0
27.05.2006, 09:42
    #33755776
ShIgor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
Вот и передизайн! :)
Нормальное решение, однако 31 мая и в этой ситуации не получить.
...
Рейтинг: 0 / 0
31.05.2006, 11:34
    #33762755
ds|Smith
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный CM
К сожалению должен вновь вернуться к данной проблеме. СМ, предложенный ShIgor работает, но при порядке 60-80 тыс. записей за месяц (а в целом их около 1млн и дальше будет больше) клиент просто умирает при обновлении =( Очень долго обрабатывается.. Дело усугубляется еще и тем, что эту же формулу я применил еще к двум другим СМ. В общем караул, давайте придумаем что-нибудь побыстрее плз =)

Решение от OldNov не подходит, т.к. нельзя заранее вычислить разницу между Оплатить до и концом периода (как это требовалось в условиях задачи), т.к. конец периода задает пользователь, а значит, он динамический. В целом картина такая: Дата - это дата когда клиент забирает у нас товар. Сумма отгрузки - сумма, на которую товар забрали. Оплатить до - дата, не позднее которой от клиента должны поступить деньги, Сумма оплаты - платеж клиента за товар.
Пользователь хочет видеть, есть ли по клиенту просрочка за этот период, т.е. для тех строк, где Оплатить до < конца периода вычисляется разность Сумма отгрузки - Сумма оплаты. Если разность > 0, то это прсрочка.
...
Рейтинг: 0 / 0
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Сложный CM / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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