将 Python SQLAlchemy 查询的结果限制为子组的最高结果
Limit results from a Python SQLAlchemy query to the top results from a subgroup
我有以下 tables:
User
id
name
Points
id
user_id
total_points(int)
user_id 是用户 table 上的外键。
在table点,每个用户可以有多个条目,例如:
user A - 1000
user B - 1500
user A - 1250
User C - 3000
User A - 500
etc...
我想得到的是table.
每个用户的前3个结果(total_points)
我可以通过这样做得到这个 table 上的所有条目:
db.session.query(Points).all()
我也可以得到玩家排序的结果:
db.session.query(Points).order_by(Points.user_id).all()
然后我可以得到按最高点到最低点排序的结果:
db.session.query(Points).order_by(Points.user_id).order_by(Points.total_points.desc()).all()
现在,我试图为每个用户只获取前 3 total_points。我正在尝试使用横向从句,但它不起作用可能是因为我不是 100% 确定如何使用它。
这是我正在尝试的:
subquery = db.session.query(User.name, Points.total_points).join(Points, Points.user_id == User.id).filter(User.id == Points.user_id).order_by(Points.user_id).order_by(Points.total_points.desc()).limit(3).subquery().lateral('top 3')
db.session.query(User.name, Points.total_points).select_from(Points).join(subquery, db.true()))
您要查找的是一个名为 rank()
的函数
这是 Postgresql doc
中的一个简单示例
SELECT depname, empno, salary,
rank() OVER (PARTITION BY depname ORDER BY salary DESC)
FROM empsalary;
depname | empno | salary | rank
-----------+-------+--------+------
develop | 8 | 6000 | 1
develop | 10 | 5200 | 2
develop | 11 | 5200 | 2
develop | 9 | 4500 | 4
develop | 7 | 4200 | 5
personnel | 2 | 3900 | 1
personnel | 5 | 3500 | 2
sales | 1 | 5000 | 1
sales | 4 | 4800 | 2
sales | 3 | 4800 | 2
(10 rows)
这是另一个问题中关于使用
的一些示例
subquery = db.session.query(
table1,
func.rank().over(
order_by=table1.c.date.desc(),
partition_by=table1.c.id
).label('rnk')
).subquery()
我有以下 tables:
User
id
name
Points
id
user_id
total_points(int)
user_id 是用户 table 上的外键。 在table点,每个用户可以有多个条目,例如:
user A - 1000
user B - 1500
user A - 1250
User C - 3000
User A - 500
etc...
我想得到的是table.
每个用户的前3个结果(total_points)我可以通过这样做得到这个 table 上的所有条目:
db.session.query(Points).all()
我也可以得到玩家排序的结果:
db.session.query(Points).order_by(Points.user_id).all()
然后我可以得到按最高点到最低点排序的结果:
db.session.query(Points).order_by(Points.user_id).order_by(Points.total_points.desc()).all()
现在,我试图为每个用户只获取前 3 total_points。我正在尝试使用横向从句,但它不起作用可能是因为我不是 100% 确定如何使用它。
这是我正在尝试的:
subquery = db.session.query(User.name, Points.total_points).join(Points, Points.user_id == User.id).filter(User.id == Points.user_id).order_by(Points.user_id).order_by(Points.total_points.desc()).limit(3).subquery().lateral('top 3')
db.session.query(User.name, Points.total_points).select_from(Points).join(subquery, db.true()))
您要查找的是一个名为 rank()
的函数
这是 Postgresql doc
SELECT depname, empno, salary,
rank() OVER (PARTITION BY depname ORDER BY salary DESC)
FROM empsalary;
depname | empno | salary | rank
-----------+-------+--------+------
develop | 8 | 6000 | 1
develop | 10 | 5200 | 2
develop | 11 | 5200 | 2
develop | 9 | 4500 | 4
develop | 7 | 4200 | 5
personnel | 2 | 3900 | 1
personnel | 5 | 3500 | 2
sales | 1 | 5000 | 1
sales | 4 | 4800 | 2
sales | 3 | 4800 | 2
(10 rows)
这是另一个问题中关于使用
subquery = db.session.query(
table1,
func.rank().over(
order_by=table1.c.date.desc(),
partition_by=table1.c.id
).label('rnk')
).subquery()