powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Выборка за интервал даты
3 сообщений из 3, страница 1 из 1
Выборка за интервал даты
    #39848954
avialaynen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дано: сбор статистики уровня смертности по районам/датам/диагнозам. Дата задана столбцом типа timestamp.
База - postgres. Реализация OLAP - Pentaho Mondrian 9.0.0.0-SNAPSHOT с гитхаба.
Нужно разделение даты на годы/месяцы/дни. Мондриан не хочет привязываться к одной колонке, требует для каждого уровня иерархии отдельную колонку. Окей, создал вьюху, с ключом date (timestamp), столбцы year, month, day (числовые).
Как с такими входными данными задать интервал с произвольными датами? Например, с 2018-02-15 до 2018-03-04. Гугл выдаёт кучу разных вариантов с двоеточиями и знаками вопроса (типа [?20180215] : [2018.03.04]). Ни один из них не заработал. Возможно, оттого, что я накосячил с выбором столбцов для уровней, возможно, из-за капризности мондриана (о ней - чуть дальше).
Окей, создаём в иерархии даты уровень "AllDate", ссылающийся на колонку date. Пытаюсь сравнить даты напрямую.
Код: java
1.
2.
3.
4.
5.
"SELECT\n"
+ "NON EMPTY {[Measures].[Death Count]} ON COLUMNS,\n"
+ "NON EMPTY FILTER({[Date.YMDHierarchy].[AllDate].Members},[Date.YMDHierarchy].[AllDate].CurrentMember.VALUE) >= CDATE('2018-02-15'))\n"
+ "    ON ROWS\n"
+ "FROM [DeathRate]";


Оказывается, что две даты напрямую сравнивать нельзя. Ну кто бы мог подумать.
Так, есть функция datediff, попробуем её.
Код: java
1.
"NON EMPTY FILTER({[Date.YMDHierarchy].[AllDate].Members},datediff(\"d\", [Date.YMDHierarchy].[AllDate].CurrentMember.VALUE, CDATE('2018-02-15') > 0)\n"


И получаем подляну от функции CDATE, потому что она не понимает формата yyyy-MM-dd.
Идём гуглить суть проблемы:
The java code behind the CDate function, invokes DateFormat.getDateInstance without parameters, returning a new instance of SimpleDateFormat.
As the style of the date isn't specified (FULL, LONG, MEDIUM or SHORT), the only accepted format is MEDIUM.

The date format is also locale specific in which case we are dealing with the default one (i.e. system locale).

In my case, this is en_GB.
Example of date style for GB:
- FULL: 16 January 2007
- LONG: 16 January 2007 - MEDIUM: 16-Jan-2007
- SHORT: 16/01/07
То есть это капризное говно понимает только один формат, зависящий от текущей локали.
Реализацию этого говна, к сожалению, так и не нашёл, хотя все исходники на руках, так что убедиться лично не удалось.
Ладно, тратим ещё полдня, чтобы разобраться, как писать собственные функции, и пишем свою функцию GetData, которая конвертирует строку в DateTime по заданному формату.
Код: java
1.
"NON EMPTY FILTER({[Date.YMDHierarchy].[AllDate].Members},datediff(\"d\", [Date.YMDHierarchy].[AllDate].CurrentMember.VALUE, GetDate('2018-02-15', 'yyyy-MM-dd')) > 0)\n"


И получаем былинный отказ уже от постгреса. Оказывается, этот mdx-запрос превращается в sql-запрос, в котором столбец даты сравнивается со столбцом даты, а для сравнения на оба операнда наворачивается функция UPPER(), как будто об этом кто-то просил, а функции UPPER с операндом типа timestamp, естественно, не существует.
Окей, наворачиваем нашу функцию GetData и на первый операнд.
Код: java
1.
"NON EMPTY FILTER({[Date.YMDHierarchy].[AllDate].Members},datediff(\"d\", GetDate([Date.YMDHierarchy].[AllDate].CurrentMember.VALUE, 'yyyy-MM-dd'), GetDate('2018-02-15', 'yyyy-MM-dd')) > 0)\n"


Теперь ломается GetDate, потому что [Date.YMDHierarchy].[AllDate].CurrentMember.VALUE внезапно почему-то выдаёт numeric.
Для диагностики меняю тип входного аргумента у GetDate, и в отладке выясняю, что [Date.YMDHierarchy].[AllDate].CurrentMember.VALUE выдаёт дабловское значение "0.0".
Может, в типе дело?
Правлю вьюху в базе, через cast(as character varying) переделываю столбцу date тип с timestamp на string. Проверяю - в столбце значения вида "2017-08-29 14:42:00". Тут всё окей. Правлю схему, добавляю новое измерение (StandardDimension вместо TimeDimension), новую иерархию, только один уровень "AllDate" типа String. В Schema Workbench схема компилится. Правда, в Saiku Analytics почему-то не добавляется.
Правлю запрос в своей джава-программе:
Код: java
1.
+ "NON EMPTY FILTER({[DateString.DateStringHierarchy].[AllDate].Members},datediff(\"d\", GetDate([DateString.DateStringHierarchy].[AllDate].CurrentMember, 'yyyy-MM-dd'), GetDate('2018-02-15', 'yyyy-MM-dd')) > 0)\n"


Теперь я точно уверен, что в AllDate стринг. Но в GetDate на вход опять приходит "0.0". В рот мне ноги, Дэвид Блэйн, как ты это сделал?
Мне нужно дёргать что-то другое, а не CurrentMember и не CurrentMember.VALUE?

Подскажите, или как сделать эту фигню нормально, или в каком именно месте я олень.
...
Рейтинг: 0 / 0
Выборка за интервал даты
    #39849971
avialaynen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всё же нашёл решение. Надо было вызывать CurrentMember.Name
Ну кто бы мог подумать, что значение поля будет лежать в Name, а не в Value, в самом-то деле.
...
Рейтинг: 0 / 0
Выборка за интервал даты
    #39850936
avialaynen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Совет всем: не пользуйтесь мондриановским FILTER для дат.
Вместо того, чтобы сгенерить sql-запрос с BETWEEN, он делает IN (и в IN - полный список всех дат, которые есть в таблице и попали в заданный интервал).
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / OLAP и DWH [игнор отключен] [закрыт для гостей] / Выборка за интервал даты
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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