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

时间:2018-07-16 19:21:09

标签: python sql sqlalchemy

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

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

首先想到的是我写了以下声明:

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(摘要):

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

没有这样的人。

所需的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循环,该循环将为第二年属于第二地区的人员选择,但这是一个昂贵且耗时的解决方案。我知道有一种方法可以执行此查询(在SET THEORY中将其称为两个集合的交集)。

2 个答案:

答案 0 :(得分:3)

您可以使用Query.intersect()将所学知识应用于SQL和SQLAlchemy:

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)

答案 1 :(得分:1)

为回应您的澄清,我更新了我的答案。您将需要为每个人使用一些标识符,这些标识符在年份/地区之间保持不变。我叫这个person_id。如果您的识别功能分布在多列中,那么此查询将稍有变化。

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类型的函数,则可能还需要一个GROUP BY语句。