Sqlalchemy查询和过滤

时间:2013-03-21 04:27:10

标签: sqlalchemy

所以我想说我有一些简单的类定义为

class Person
    birthday

class Address
    state

我想要每个州最年长的人,我想我能得到它 像

这样的东西
db.session.query(Address).order_by(Person.birthday.desc()).first()

但现在我又添加了另一个类

class pet
    species

我希望找到每个州每个州最年长的人 所以从下面......

john - MI - dog - 50
alex - MI - dog - 51
joe  - MI - cat - 10
tina - FL - cat - 20

我只想要

alex, joe, tina

但不是约翰,因为他不是最老的。

我如何构建一个查询来执行此操作。我应该学习哪些主题 大约?

到目前为止,这是我最好的尝试。此代码特定于我的数据库:

def most_recent_completed_uss(user):
    lids = []
    for o in user.organizations:
        for sh in o.survey_headers:
            for ss in sh.survey_sections:
                l = datetime.datetime(1,1,1)
                lid = None
                for uss in ss.user_survey_sections:
                    if o.id == uss.organization.id:
                        if l == datetime.datetime(1,1,1):
                            lid = uss.id
                        if (uss.completed_date and uss.completed_date >= l):
                            l = uss.completed_date
                            lid = uss.id
                lids.append(lid)
    return lids

当然,4个嵌套for循环和缺乏查询使我认为这是一个不太理想的解决方案。

1 个答案:

答案 0 :(得分:0)

如果你正在使用PostgreSQL,你可以使用DISTINCT ON(...),它取每组中的第一行。在python:

session.query(Person)
.join(Address, Pet)
.distinct(Address.state, Pet.species)
.order_by(Address.state, Pet.species, Person.birthday)

这将产生类似于:

SELECT DISTINCT ON(address.state, pet.species) person.*
FROM person
JOIN address ON person.address_id = address.id
JOIN pet ON pet.owner_id = person.id
ORDER BY address.state, pet.species, person.birthday