2014-01-21 31 views
7

您好我是一個小預測遊戲工作在燒瓶燒瓶SQLAlchemy的我有一個用戶模式的總和計數加盟: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() 

他們都工作順利拿到這個名單,但我認爲必須有一種方式來獲得兩個querys在一起,並得到一個表的用戶名,分「hitcount」。我以前在SQL中做過這些,但我並不熟悉SQLAlchemy,並且在我的大腦中想到了結。我怎樣才能在一個查詢兩個查詢?

回答

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()) 
    ) 

注意,我改變了要使用的是SELECT,一些數據庫引擎可能會抱怨,否則列GROUP_BY條款。但你不需要這樣做。

+0

它非常接近,但它爲每個用戶總結所有點,如果user1有兩個投注點3點,並且user2有兩個投注一個2點一個1點,輸出是[(u'user1',9,2 ),(u'user2',9,2)] – bknux

+0

所以,這個工程:¸toplist= db.session.query(User.nick,func.sum(Bet.points),func.sum(case(value = Bet (用戶.bets).group_by(Bet.uid).order_by(func.sum(Bet.points).desc())。所有()¸ – bknux

+0

你是對的:錯過'join(User.bets)'(添加到答案)。 – van