首页 > 解决方案 > SQLAlchemy 仅 func.rank() 表中 value = x 的行

问题描述

在我上一个问题中,我设法根据该表在该表中的值来获得该表的排名。我现在可以根据给定的分数对电影进行排名(使用下表和方法)

class MoviePersonScores(db.Model):
     movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'), primary_key=True)
     person_id = db.Column(db.Integer, db.ForeignKey('person.id'), primary_key=True)
     score = db.Column(db.Integer)
     person = relationship("Person", back_populates="movies")
     movie = relationship("Movie", back_populates="people")

@YaakovBressler提供的答案:

from sqlalchemy import func

query = session.query(
    MoviePersonScores, 
    func.rank()\
        .over(
            order_by=MoviePersonScores.score.desc()
        )\
        .label('rank')
)
# now filter
query = query.filter_by(movie_id=movie_id)
# now execute:
my_movie = query.all()

这对于获取所有行的排名非常有用。但现在我想根据其中的人进行排名。所以person_id可能是导演的ID,所以现在如果我想要所有昆汀塔伦蒂诺电影的排名,我首先需要过滤他所有电影的数据库然后应用排名,那么我将如何使用上述方法在已经查询和过滤的一组行上?

先感谢您!

标签: pythonsqlalchemy

解决方案


这个新查询的解决方案将与前一个类似,不同之处在于您将包含一个partition_by类似于groupby方法的参数,以及filter_by指定您的给定person_id

query = session.query(
    MoviePersonScores, 
    func.rank()\
        .over(
            order_by=MoviePersonScores.score.desc(),
            partition_by=MoviePersonScores.person_id,
        )\
        .label('rank')
)

# If you want to filter for a specific person, filter your query
my_person_id = 1 # substitute this for the correct id
query = query.filter(MoviePersonScores.person_id == my_person_id)

# I'd suggest ordering by the person_id, so you get neat results when debugging
query = query.order_by(MoviePersonScores.person_id, 'rank')

# Convert to a subquery so you can apply more filters
all_movies = query.subquery()

# Now filter your subquery based on a specific movie
movie_id = 1 # some movie ID
query = session.query(all_movies).filter(all_movies.c.movie_id == movie_id)

# Get all results
result = query.all()

推荐阅读