简体   繁体   English

SQLAlchemy如何合并查询

[英]SQLAlchemy how to merge queries

I am trying to create a database for a chess league I am trying to create. 我正在尝试为我想创建的国际象棋联赛创建数据库。

I have written the query below which gives me the result I want but it looks very long-winded and I'd like a second opinion on how it could be written better. 我在下面编写了查询,该查询可以为我提供所需的结果,但是它看起来很冗长,我想就如何更好地编写它提出第二个意见。

I have two tables, one represents a team and another a "board". 我有两个表,一个代表一个团队,另一个代表“董事会”。 The board holds the result for each player and the board number they played. 董事会保留每个玩家的成绩和所玩的董事会编号。

class Board(db.Model):
    __tablename__ = 'board'
    id = db.Column(db.Integer, primary_key=True)
    board_number = db.Column(db.Integer)
    team_id = db.Column(db.Integer, db.ForeignKey("team.id"))
    result = db.Column(db.Float)

class Team(db.Model):
    __tablename__ = 'team'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    boards = db.relationship('Board', backref='teams', lazy=True)

So to calculate the league table I have created 4 different queries: wins, losses, draws and total points. 因此,要计算联赛表,我创建了4个不同的查询:胜利,失败,平局和总分。

They are then joined together and ordered by total points to create the league table. 然后将它们合并在一起,并按总分排序以创建联赛表。

    wins = (
    db.session.query(Team.id,
                     db.func.count(Board.result).label('win')
                     )
    .filter(Team.league_id == 1)
    .join(Board).filter_by(team_id=Team.id, result=1)
    .group_by(Team.id)
    .subquery()
)



losses = (
    db.session.query(Team.id,
                     db.func.count(Board.result).label('loss')
                     )
    .filter(Team.league_id == 1)
    .join(Board).filter_by(team_id=Team.id, result=0)
    .group_by(Team.id)
    .subquery()
)


draws = (
    db.session.query(Team.id,
                     db.func.count(Board.result).label('draw')
                     )
    .filter(Team.league_id == 1)
    .join(Board).filter_by(team_id=Team.id, result=0.5)
    .group_by(Team.id)
    .subquery()
)

total_points = (
    db.session.query(Team.id,
                     db.func.sum(Board.result).label('total')
                     )
    .filter(Team.league_id == 1)
    .join(Board, (Board.team_id == Team.id))
    .group_by(Team.id)
    .subquery()
)


league_table = (
    db.session.query(Team.name, wins.c.win, draws.c.draw, losses.c.loss, total_points.c.total)
    .join((wins, wins.c.id == Team.id))
    .join((losses, losses.c.id == Team.id))
    .join((draws, draws.c.id == Team.id))
    .join((total_points, total_points.c.id == Team.id))
    .order_by((total_points.c.total).desc())
    .all()
)

Could the 4 queries be merged into one? 4个查询可以合并为一个吗?

The queries can be performed in a single query using the aggregate FILTER clause: 可以使用聚合FILTER子句在单个查询中执行查询:

If FILTER is specified, then only the input rows for which the filter_clause evaluates to true are fed to the aggregate function; 如果指定了FILTER ,则只有filter_clause评估为true的输入行才被馈送到聚合函数;

In SQLAlchemy you can use FunctionElement.filter() to produce the clause: 在SQLAlchemy中,您可以使用FunctionElement.filter()生成子句:

db.session.query(
        Team.name,
        db.func.count(Board.result).filter(Board.result == 1).label('win'),
        db.func.count(Board.result).filter(Board.result == 0).label('loss'),
        db.func.count(Board.result).filter(Board.result == 0.5).label('draw'),
        db.func.sum(Board.result).label('total'))\
    .join(Board)\
    .filter(Team.league_id == 1)\
    .group_by(Team.id)\
    .order_by(db.func.sum(Board.result).desc())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM