ПРИМЕНЕНИЕ КРЕСТА в SQLAlchemy? - PullRequest
1 голос
/ 29 января 2020

Можно ли в SQLAlchemy копировать функциональность перекрестного и внешнего применения? В настоящее время у меня есть запрос SQL, чтобы выполнить простой тип вычисления возвращаемого значения:

SELECT id.ID, id.Name, a.AsOfDate AS CurrentDate, b.AsOfDate AS PriorDate, ((a.RetVal - b.RetVal) / b.RetVal) * 100
FROM (
    SELECT mpp.RetID AS ID, act.Name
    FROM Account act 
    JOIN Mapping mpp ON act.AccID = mpp.AccID
    ) id
CROSS APPLY(SELECT TOP 1 * FROM TotalReturns ret WHERE id.ID = ret.ID AND ret.AsOfDate <= DATEADD(MONTH, -1, GETDATE()) ORDER BY ret.AsOfDate DESC) a
CROSS APPLY(SELECT TOP 1 * FROM TotalReturns ret2 WHERE id.ID = ret2.ID AND ret2.AsOfDate <= DATEADD(MONTH, -2, GETDATE()) ORDER BY ret2.AsOfDate DESC) b

Мне удалось воспроизвести те же логи c в SQLAlchemy, используя подзапросы и используя функцию row_number, чтобы получить последние даты, однако производительность значительно ниже:

current_data = (
    session
    .query(
        mapping_query.c.id.label('id'),
        db.TotalReturns.as_of_date.label('current_date'),
        db.TotalReturns.gross_total_return.label('current_total_return'),
        func.row_number().over(partition_by=db.TotalReturns.id, order_by=(db.TotalReturns.as_of_date.desc())).label("row_number")
    )
    .join(mapping_query, db.TotalReturns.id == mapping_query.c.id)
    .filter((mapping_query.c.id.in_(id_list)) & (db.TotalReturns.as_of_date <= current_date))
    .subquery()
)

prior_data = (
    session
    .query(
        mapping_query.c.id,
        db.TotalReturns.as_of_date.label('prior_date'),
        db.TotalReturns.gross_total_return.label('prior_total_return'),
        func.row_number().over(partition_by=db.TotalReturns.id, order_by=(db.TotalReturns.as_of_date.desc())).label("row_number")
    )
    .join(mapping_query, db.TotalReturns.id == mapping_query.c.id)
    .filter((mapping_query.c.id.in_(id_list)) & (db.TotalReturns.as_of_date <= prior_date))
    .subquery()
)

query = (
    session
    .query(
        current_data.c.id,
        current_data.c.current_total_return,
        current_data.c.current_date,
        prior_data.c.prior_total_return,
        prior_data.c.prior_date
    )
    .join(prior_data, current_data.c.id == prior_data.c.id)
    .filter((current_data.c.row_number == 1) & (prior_data.c.row_number == 1))
)

Есть ли способ использовать оператор apply при построении кода в python и без непосредственного использования SQL?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...