使用 SQLAlchemy ,我与两个表有一对多关系 - 用户和分数。我正在尝试查询在过去 X 天内按总分排序的前 10 名用户。
users:
id
user_name
score
scores:
user
score_amount
created
我当前的查询是:
top_users = DBSession.query(User).options(eagerload('scores')).filter_by(User.scores.created > somedate).order_by(func.sum(User.scores).desc()).all()
我知道这显然不正确,这只是我最好的猜测。但是,在查看文档和谷歌搜索后,我找不到答案。
编辑: 如果我勾勒出 MySQL 的内容,也许会有帮助查询看起来像:
SELECT user.*, SUM(scores.amount) as score_increase
FROM user LEFT JOIN scores ON scores.user_id = user.user_id
WITH scores.created_at > someday
ORDER BY score_increase DESC
最佳答案
单连接行方式,为所有用户列添加一个group_by
,如果您选择,MySQL 将允许您仅在“id”列上分组:
sess.query(User, func.sum(Score.amount).label('score_increase')).\
join(User.scores).\
filter(Score.created_at > someday).\
group_by(User).\
order_by("score increase desc")
或者如果您只希望结果中包含用户:
sess.query(User).\
join(User.scores).\
filter(Score.created_at > someday).\
group_by(User).\
order_by(func.sum(Score.amount))
以上两个方法的效率低下,因为您要对“用户”的所有列进行分组(或者您使用的是 MySQL 的“仅在几列上分组”,这仅适用于 MySQL)。为了尽量减少这种情况,子查询方法:
subq = sess.query(Score.user_id, func.sum(Score.amount).label('score_increase')).\
filter(Score.created_at > someday).\
group_by(Score.user_id).subquery()
sess.query(User).join((subq, subq.c.user_id==User.user_id)).order_by(subq.c.score_increase)
ORM 教程中有一个相同场景的示例:http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#selecting-entities-from-subqueries
关于python - SQLAlchemy 按相关对象过滤查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2010454/