Python 按SQLAlchemy排序的子查询
我正在尝试将SQL查询转换为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
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