在SQLAlchemy中使用func rank对表中的行进行排名

时间:2016-04-23 00:41:12

标签: python sql postgresql sqlalchemy

我有一个像这样定义的表:

   Column    |  Type   | Modifiers | Storage | Stats target | Description
-------------+---------+-----------+---------+--------------+-------------
 id          | uuid    | not null  | plain   |              |
 user_id     | uuid    |           | plain   |              |
 area_id     | integer |           | plain   |              |
 vote_amount | integer |           | plain   |              |

我希望能够在查询此数据库时生成排名“列”。此排名列将按vote_amount列排序。我试图创建一个查询来执行此操作,它看起来像这样:

subq_rank = db.session.query(user_stories).add_columns(db.func.rank.over(partition_by=user_stories.user_id, order_by=user_stories.vote_amount).label('rank')).subquery('slr')
data = db.session.query(user_stories).select_entity_from(subq_rank).filter(user_stories.area_id == id).group_by(-subq_rank.c.rank).limit(50).all()

希望我的尝试能让你了解我想要实现的目标。

感谢。

1 个答案:

答案 0 :(得分:0)

好吧,如果您在每个查询中都需要这些列,那么我会在DB中做得更好。我将创建一个包含列排名的视图,并在查询中调用该视图以直接显示代码中的数据:

CREATE VIEW [ranking_user_stories] AS
SELECT TOP 50 * FROM 
(SELECT *, rank() over (partition by user_stories.user_id order by user_stories.vote_amount ASC) AS ranking
FROM user_stories
WHERE user_stories.area_id = id) uS
ORDER BY vote_amount ASC

这与代码的逻辑相同,但是在SQL中,如果您使用的是MySQL,只需将TOP 50更改为LIMIT 50(并放在查询末尾)。我认为按排名排在最后一组是没有意义的,但是如果您需要的话:

CREATE VIEW [ranking_user_stories] AS
    SELECT TOP 50 MAX(id) AS id, user_id, area_id, MAX(vote_amount) AS vote_amount, ranking FROM 
    (SELECT *, rank() over (partition by user_stories.user_id order by user_stories.vote_amount ASC) AS ranking
    FROM user_stories
    WHERE user_stories.area_id = id) uS
    ORDER BY MAX(vote_amount) ASC
    GROUP BY user_id, area_id, ranking