2016-11-25 114 views
0

我想使用SQLAlchemy编写SQL Server的外部应用查询,如下所示。SQLAlchemy中的OUTER APPLY

FX表可能没有价格表中的日期对应的行,所以我需要使用OUTER APPLY来获取每个日期的FX表中的最后一行。

SELECT p.EffectiveDate, p.Close_ * FX.Rate as USD_PRICE 
FROM PRICE p 
OUTER APPLY (
    SELECT TOP 1 * 
    FROM FX 
    WHERE 
     FromCurrency = p.Currency 
     AND ToCurrency = 'USD' 
     AND ExRateDate <= p.EffectiveDate 
    ORDER BY ExRateDate DESC 
) fx 

在表简要背景:

  • 价格表是一个时间序列,其具有EFFECTIVEDATE,货币和Close_柱。有效日期是主键。
  • FX表具有FromCurrCode,ToCurrCode,ExRateDate和Rate列。主键是(FromCurrCode,ToCurrCode,ExRateDate)
  • 我的用例是加入PRICE和FX表格以获得美元价格。但是,对于PRICE表中给定的EffectiveDate,该日期的FX表中可能没有行。因此,表格不能直接与FX.ExRateDate = PRICE.EffectiveDate连接。要解决这个问题,我需要使用OUTER APPLY来查找FX台的FX.ExRateDate是最接近PRICE.EffectiveDate最后一行

看来,SQLAlchemy的不支持外表达应用。我看了一下Custom SQL Constructs and Compilation Extension。但我不确定如何创建outer apply的自定义构造。你有这样的例子吗?

我想一个解决方法是用outer join替换outer apply。如果你可以提供一个查询可以产生相同的结果而不使用outer apply,那也可以解决我的问题。

感谢

回答

0

使用Correlated Subquery这里是解决方案使用OUTER JOIN

sq = (
    session.query(FX.id.label("last_id")) 
    .filter(FX.FromCurrency == Price.Currency) 
    .filter(FX.ToCurrency == 'USD') 
    .filter(FX.ExRateDate <= Price.EffectiveDate) 
    .order_by(FX.ExRateDate.desc()) 
    .order_by(FX.id.desc()) # handle duplicates just in case 
    .limit(1) 
    .correlate(Price) 
    .as_scalar() 
) 

q = session.query(
    Price.EffectiveDate, 
    (Price.Close_ * FX.Rate).label("USD_PRICE"), 
).outerjoin(FX, FX.id == sq)