您好我正在使用flask-sqlalchemy在烧瓶中进行一个小预测游戏我有一个用户模型:
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
nick = db.Column(db.String(255), unique=True)
bets = relationship('Bet', backref=backref("user"))
和我的投注模型
class Bet(db.Model):
id = db.Column(db.Integer, primary_key=True)
uid = db.Column(db.Integer, db.ForeignKey('user.id'))
matchid = db.Column(db.Integer, db.ForeignKey('match.id'))
points = db.Column(db.Integer)
两者都不是完整的类,但它应该为问题做。用户可以收集用于预测匹配结果的点,并获得用于预测确切结果,获胜者或差异的不同点数。 我现在想要一个顶级用户列表,我必须总结我正在做的点
toplist = db.session.query(User.nick, func.sum(Bet.points)).\
join(User.bets).group_by(Bet.uid).order_by(func.sum(Bet.points).desc()).all()
这很有效,现在可能有两个玩家拥有相同点数的情况。在这种情况下,正确预测的数量(奖励3分)将定义胜利者。我可以通过
获取此列表tophits = db.session.query(User.nick, func.count(Bet.points)).\
join(User.bets).filter_by(points=3).all()
它们都运行良好,但我认为必须有一种方法可以将两个查询放在一起,并获得一个包含用户名,积分和“hitcount”的表格。我之前在SQL中已经完成了这项工作,但我并不熟悉SQLAlchemy,并且认为我脑子里有结。如何将两个查询合二为一?
答案 0 :(得分:9)
在tophits
的查询中,只需将COUNT/filter_by
构造替换为不含SUM(CASE(..))
的等效filter
,以便两者的WHERE
子句相同。下面的代码应该这样做:
total_points = func.sum(Bet.points).label("total_points")
total_hits = func.sum(case(value=Bet.points, whens={3: 1}, else_=0)).label("total_hits")
q = (session.query(
User.nick,
total_points,
total_hits,
)
.join(User.bets)
.group_by(User.nick)
.order_by(total_points.desc())
.order_by(total_hits.desc())
)
请注意,我更改了一个group_by子句以使用SELECT中的列,因为某些数据库引擎可能会抱怨。但你不需要这样做。