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