Python 如何在SQLAlchemy中编写多组件嵌套连接约束

Python 如何在SQLAlchemy中编写多组件嵌套连接约束,python,sql,sqlalchemy,Python,Sql,Sqlalchemy,我希望能够为包含两组双条件的所有行进行选择 作为一个例子,我正在处理一个人口被划分为不同的地区,每年都在变化。我想查询一年中属于一个地区,另一年属于另一个地区的所有人的子集 正如我最初所想,我写了以下声明: session.Query(People).join(District, People.district).filter(and_(and_(District.year == 2015, District.num == 5), and_(District.year == 2016, Dist

我希望能够为包含两组双条件的所有行进行选择

作为一个例子,我正在处理一个人口被划分为不同的地区,每年都在变化。我想查询一年中属于一个地区,另一年属于另一个地区的所有人的子集

正如我最初所想,我写了以下声明:

session.Query(People).join(District, People.district).filter(and_(and_(District.year == 2015, District.num == 5), and_(District.year == 2016, District.num == 6))).all()
但是,这会产生SQL(总结):

没有这样的人

所需的SQL语句应大致如下:

SELECT * FROM database.table JOIN district ON address.district WHERE ( district.year == 2015 AND district.num == 5 ) AND ( district.year == 2016 AND district.num == 6 )
澄清1:更改了SQL语句,并在下面添加了更多解释

为了澄清这一点,每年都会有一些地区,但它们会发生变化,所以每个地区都有一年的时间。我正在寻找一年属于一个地区,明年属于另一个重叠地区的人的子集


最后,我把一个地区的所有人都拉了出来,然后创建了一个FOR循环,在下一年为属于第二个地区的人选择,但这是一个昂贵且耗时的解决方案。我知道有一种方法可以执行此查询(在集合论中,这称为两个集合的交集)。

为了回应您的澄清,我更新了我的答案。您需要为每个人使用一些标识符,这些标识符在不同年份/地区保持不变。我已经给这个人打过电话了。如果你的识别功能分布在多个列上,那么这个查询会有轻微的变化

SELECT DISTINCT t1.person_id , ... 
FROM database.table AS t1
INNER JOIN database.table AS t2
  ON t2.person_id = t1.person_id
WHERE 
  (t1.year =='2015' AND t1.district == 5) 
AND 
  (t2.year =='2016' AND t2.district ==6)

需要一个
DISTINCT
来过滤掉重复的行。如果您正在执行
聚合
类型功能,那么您可能还需要一个
分组依据
语句。

为了回应您的澄清,我更新了我的答案。您需要为每个人使用一些标识符,这些标识符在不同年份/地区保持不变。我已经给这个人打过电话了。如果你的识别功能分布在多个列上,那么这个查询会有轻微的变化

SELECT DISTINCT t1.person_id , ... 
FROM database.table AS t1
INNER JOIN database.table AS t2
  ON t2.person_id = t1.person_id
WHERE 
  (t1.year =='2015' AND t1.district == 5) 
AND 
  (t2.year =='2016' AND t2.district ==6)

需要一个
DISTINCT
来过滤掉重复的行。如果您正在执行
Aggregate
类型函数,那么您可能还需要一个
groupby
语句。

您可以使用以下方法应用SQL和SQLAlchemy中的设置知识:


您可以使用以下方法在SQL和SQLAlchemy中应用您的集合知识:


没有,我没有解释清楚。我在寻找两个不同数据集的交集,事实上,它们应该是和语句(我认为是)不。我没有很好地解释我自己。我在寻找两个不同数据集的交集,事实上,它们应该是和语句(我认为是)对不起,我最初没有很好地解释我自己。我已经更新了问题,以反映我正在尝试做的事情。简言之,你所提出的是两组不同数据的并集,我只是在寻找交集。谢谢你的回复,我希望我现在能更好地描述我的问题。谢谢爱德华。这将是正确的SQL答案,尽管我使用的是ORM,并且发现.intersect方法做了我需要它做的事情:很好,我将保留它,以防它对其他人起作用。如果
Query.Intersect
按预期工作,那么它们也应该做同样的事情。对不起,我最初没有很好地解释我自己。我已经更新了问题,以反映我正在尝试做的事情。简言之,你所提出的是两组不同数据的并集,我只是在寻找交集。谢谢你的回复,我希望我现在能更好地描述我的问题。谢谢爱德华。这将是正确的SQL答案,尽管我使用的是ORM,并且发现.intersect方法做了我需要它做的事情:很好,我将保留它,以防它对其他人起作用。如果
Query.Intersect
按预期工作,那么它们也应该做同样的事情。谢谢。事实上,就在我发布了澄清之后,我突然明白了我应该用什么术语来谷歌回复。谢谢。删除了关于连接的部分,因为我认为它可能被误解了。它们值得学习,因为它们在关系数据库/SQL中非常强大,尽管在开始时有时有点让人望而生畏,如果必须进行自连接,或者多次连接到同一个表等等。事实上,就在我发布了澄清之后,我突然明白了我应该用什么术语来谷歌回复。谢谢。删除了关于连接的部分,因为我认为它可能被误解了。它们是值得学习的,因为它们在关系数据库/SQL中非常强大,但如果必须进行自连接或多次连接到同一个表等操作,一开始有时会有点让人望而生畏。
q1 = session.query(People).\
    join(People.district).\
    filter(District.year == 2015, District.num == 5)

q2 = session.query(People).\
    join(People.district).\
    filter(District.year == 2016, District.num == 6)

q = q1.intersect(q2)