Привет, Хабр! DAX является мощным аналитическим языком запросов и активно используется во множестве проектов. Кроме того, на текущем уровне развития AI он способен условно в режиме реального времени преобразовать DAX запросы в запросы одной из СУБД, например, PostgreSQL, но, конечно, с рядом ограничений на сложность DAX запроса, схему данных и т.д. В связи с этим может быть актуальным вопрос, реально ли использовать «AI DAX движок» в сочетании с выполнением SQL запросов, сгенерированных этим движком, в одной из СУБД, т.е. выполнить DAX без Power BI на PostgreSQL источнике? Интересующимся возможностями DAX AI на примере PostgreSQL — добро пожаловать под кат :)
Раньше был рассмотрен DAX запрос для SUMMARIZECOLUMNS
, и сейчас он тоже выглядит актуально. Рассмотрим часть схемы из dax.do с таблицей фактов Sales
и таблицей клиентов Customer
.

Также пусть есть DAX запрос, который, как было рассмотрено раньше, достаточно успешно преобразуется в SQL для PostgreSQL:
EVALUATE
SUMMARIZECOLUMNS (
Customer[Cars Owned],
FILTER ( Sales, Sales[Quantity] > AVERAGE ( Sales[Quantity] ) ),
FILTER ( Customer, Customer[Cars Owned] > 1 ),
"Calculated Quantity",
CALCULATE (
SUMX ( Sales, Sales[Quantity] * RELATED ( Customer[Cars Owned] ) ),
REMOVEFILTERS ( Sales[Quantity] ),
FILTER ( Customer, Customer[Cars Owned] < 4 )
)
)
Условный «DAX AI движок» генерирует PostgreSQL для этого DAX за доли секунды через OpenAI API, за счет простого запроса.
SELECT "Cars Owned", SUM(Quantity * "Cars Owned") AS "Calculated Quantity"
FROM sales
WHERE Quantity > (SELECT AVG(Quantity) FROM sales)
AND "Cars Owned" > 1
AND "Cars Owned" < 4
GROUP BY "Cars Owned"
Выглядит неплохо, как и было рассмотрено раньше, теперь осталось выполнить этот SQL на PostgreSQL, и тогда это и будет условный «AI DAX движок для PostgreSQL без Power BI».
Пока такой функционал существует лишь в виде прототипа на сайте портфолио, тем не менее, результаты могут выглядеть достаточно интересно.

Видно, что выводится результат «DAX AI движка» — SQL для PostgreSQL, соответствующий исходному DAX, а также таблица с результатами выполнения запроса.
Как и в прошлый раз, для упрощения работы AI использована денормализованная таблица Sales
, однако сейчас количество тестовых записей в Sales
не 50 миллионов, а всего лишь 500 — для упрощения разработки, также добавлены всего 2-3 поля из таблиц, а не все поля таблиц Customer
и Sales
из dax.do:
CREATE TABLE sales
(
"Order Number" INTEGER,
CustomerKey INTEGER,
"Cars Owned" INTEGER,
Quantity INTEGER
);
INSERT INTO sales("Order Number", CustomerKey, ""Cars Owned"", Quantity)
SELECT number + 100000000 AS "Order Number",
number % 20 AS CustomerKey,
number % 20 % 5 AS "Cars Owned",
number % 10 AS Quantity
FROM generate_series(1, 500) as number;
В рамках описанной схемы данных с двумя таблицами Sales
и Customer
запрос DAX может быть «условно произвольным», всё зависит от возможностей AI. Например, если добавить в исходный DAX выражение вида 1 + 2 * CALCULATE ( ... )
, то можно заметить креатив от AI в сгенерированном SQL и использование CTE.
EVALUATE
SUMMARIZECOLUMNS (
Customer[Cars Owned],
FILTER ( Sales, Sales[Quantity] > AVERAGE ( Sales[Quantity] ) ),
FILTER ( Customer, Customer[Cars Owned] > 1 ),
"Calculated Quantity",
1 + 2 * CALCULATE (
SUMX ( Sales, Sales[Quantity] * RELATED ( Customer[Cars Owned] ) ),
REMOVEFILTERS ( Sales[Quantity] ),
FILTER ( Customer, Customer[Cars Owned] < 4 )
)
)
WITH filtered_sales AS (
SELECT "Cars Owned", Quantity
FROM sales
WHERE Quantity > (
SELECT AVG(Quantity) FROM sales
)
)
SELECT "Cars Owned",
SUM(Quantity * "Cars Owned") AS "Calculated Quantity",
1 + 2 * SUM(Quantity * "Cars Owned") AS "Final Quantity"
FROM filtered_sales
WHERE "Cars Owned" > 1 AND "Cars Owned" < 4
GROUP BY "Cars Owned"
Или, в полном виде, введённый DAX, результаты AI DAX движка и результаты выполнения PostgreSQL запроса для измененного DAX (с выражением) выглядят следующим образом.

Надеюсь, результаты могут быть интересны при создании дашбордов и работе с Business Intelligence. Желаю успехов в BI и дашбордах :)
Комментарии (4)
koanse Автор
13.01.2025 08:35прикручивать его было бы логичней к CH, а не к PostgreSQL
Да, это и имплементировано, например, в Visiology и DAX Visiology работает в ClickHouse.
В этой статье PostgreSQL взята в качестве примера СУБД, можно взять любую другую.
Вопрос же о весьма сомнительных преимуществах DAX перед SQL оставим за скобками
Такое впечатление, что описанный подход полезен при любом отношении к DAX в сравнении с SQL:
если DAX "нравится", то расширяются возможности его применения;
если DAX по каким-то причинам "не нравится", то рассматривается получение SQL, соответствующего DAX.
ptr128
13.01.2025 08:35Да, это и имплементировано, например, в Visiology и DAX Visiology работает в ClickHouse.
За эту информацию спасибо!
при любом отношении к DAX в сравнении с SQL
Вопрос не в нравится или не нравится. Вопрос в том, что для того, чтобы достаточно сложные конструкции DAX перевести на PostgreSQL, потребуются значительные усилия в целях оптимизации результирующего запроса. И если пользователь SQL может ознакомиться с планом запроса и сделать соответствующие выводы, то пользователь DAX будет не понимать, почему его запрос не может часами выполниться. И никакой понятной ему информации предоставить будет невозможно.
koanse Автор
13.01.2025 08:35Вопрос не в нравится или не нравится
Да, в общем случае я имел в виду не только эмоции разработчиков и их отношение к технологиям, но больше настроения и планы лиц, принимающих решения, с учетом затрат человеко-часов, компетенций разработчиков, стратегии развития компании и т.д.
ptr128
Исходя из того, что DAX - язык аналитических запросов, то прикручивать его было бы логичней к CH, а не к PostgreSQL.
Вопрос же о весьма сомнительных преимуществах DAX перед SQL оставим за скобками.