嗨,我正在使用flask-sqlalchemy在Flask中进行一些小预测游戏,我有一个用户模型:
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和大脑中的思想难题并不那么熟悉。如何将两个查询合而为一?
在查询tophits只需更换COUNT/filter_by具有同等构造SUM(CASE(..))不filter使WHERE两个条款是一样的。下面的代码应该做到这一点:
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中的列,因为某些数据库引擎可能会抱怨。但是您不需要这样做。