[英]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 thefilter_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.