Выполнение DAX запроса AI DAX движка в СУБД на примере PostgreSQL
Привет, Хабр! 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 и дашбордах :)