Python 按SQLAlchemy排序的子查询

Python 按SQLAlchemy排序的子查询,python,sql,sqlalchemy,subquery,Python,Sql,Sqlalchemy,Subquery,我正在尝试将SQL查询转换为SQLAlchemy查询语言。 为了稍微了解查询的含义,我有一个表安全性和一个表赋值。 证券表描述了我在市场上关注的不同证券股票: id | bbg_ticker ------+------------------------- 1 | 3993 HK Equity 2 | A2A IM Equity 3 | AA UN Equity 4 | AA/ LN Equity 5 | AAL LN Equit

我正在尝试将SQL查询转换为SQLAlchemy查询语言。 为了稍微了解查询的含义,我有一个表安全性和一个表赋值。 证券表描述了我在市场上关注的不同证券股票:

 id   |           bbg_ticker
------+-------------------------
    1 | 3993 HK Equity
    2 | A2A IM Equity
    3 | AA UN Equity
    4 | AA/ LN Equity
    5 | AAL LN Equity
    6 | AALB NA Equity
    7 | ABBN VX Equity
估价表描述了一种证券和一天的价值:

我想做的是在一个精确的日期,按数量分类,选出第十名最佳证券。问题是,有时没有这个特定日期的数据,例如周末,所以我想取过去最接近的最后一个卷值

我在纯SQL中找到了解决方案,以下是2015年5月23日的一个示例:

SELECT s.bbg_ticker
FROM security s
INNER JOIN valuation v1
    ON v1.security_id = s.id
    AND v1.volume IS NOT NULL
    AND v1.px_close iS NOT NULL
    AND v1.date > '2015-05-16'     # because I don't want too old values..
    AND v1.date <= '2015-05-23'
GROUP BY s.id
ORDER BY (SELECT v.volume
    FROM valuation v
    WHERE v.security_id = s.id
        AND v.volume IS NOT NULL
        AND v.px_close IS NOT NULL
        AND v.date > '2015-05-16'  # same
        AND v.date <= '2015-05-23'
    ORDER BY v.date DESC LIMIT 1
) DESC
LIMIT 10
我想做同样的事情,但是使用SQLAlchemy查询语言。由于在我的SQL查询中有很多重复,我非常确信我可以在不重复的情况下用SQLAlchemy做一些更聪明的事情

我无法使用SQLAlchemy在ORDER BY中执行子查询

有人有主意吗

谢谢,,

编辑:

我的第一个想法是这样做:

 Security.query.join(Valuation)\
      .filter(
          Valuation.volume != None,
          Valuation.px_close != None,
          Valuation.date <= date(2015, 05, 23),
          Valuation.date > date(2015, 05, 16)
      ).order_by(
          db.session.query(Valuation.volume).filter(
              Valuation.volume != None,
              Valuation.px_close != None,
              Valuation.date <= date(2015, 05, 23),
              Valuation.date > date(2015, 05, 16)
          ).desc()
      )
但是:

我有一个关于desc:AttributeError的错误:“BaseQuery”对象没有属性“desc” 我在子查询中没有v.security\u id=s.id的链接,因为我无法访问子查询中的安全性
我最终找到了解决办法:

Security.query.join(Valuation)\
        .filter(tuple_(Valuation.security_id, Valuation.date).in_(
            db.session.query(Valuation.stock_id, func.max(Valuation.date))\
            .filter(Valuation.volume != None,
                    Valuation.px_close != None,
                    Valuation.date > date(2015, 05, 16),
                    Valuation.date <= date(2015, 05, 23))
            .group_by(Valuation.security_id)))
            .order_by(Valuation.volume.desc())
            .limit(10)
            .all()
产生:

SELECT security.*
FROM security
    JOIN valuation ON security.id = valuation.security_id
    WHERE (valuation.security_id, valuation.date) IN (
        SELECT valuation.security_id, max(valuation.date)
        FROM valuation
        WHERE valuation.volume IS NOT NULL
            AND valuation.px_close IS NOT NULL
            AND valuation.date > "2015-05-16"
            AND valuation.date <= "2015-05-23"
            GROUP BY valuation.security_id
    )
ORDER BY valuation.volume DESC
LIMIT 10
这是更有效的,不需要重复

SELECT security.*
FROM security
    JOIN valuation ON security.id = valuation.security_id
    WHERE (valuation.security_id, valuation.date) IN (
        SELECT valuation.security_id, max(valuation.date)
        FROM valuation
        WHERE valuation.volume IS NOT NULL
            AND valuation.px_close IS NOT NULL
            AND valuation.date > "2015-05-16"
            AND valuation.date <= "2015-05-23"
            GROUP BY valuation.security_id
    )
ORDER BY valuation.volume DESC
LIMIT 10