排除连接表中没有关联行的行

Bri*_*ach 3 python sqlalchemy

我想获取表foo中没有引用的实例(行)bar

foo

+----+-----+
| id | baz |
+----+-----+
|  1 |  23 |
|  2 |  56 |
|  3 |  45 |
|  4 |  78 |
+----+-----+
Run Code Online (Sandbox Code Playgroud)

bar

+-----+--------+-----+
| id  | foo_id | zab |
+-----+--------+-----+
|  7  |      2 | s1  |
|  8  |      4 | s2  |
+-----+--------+-----+
Run Code Online (Sandbox Code Playgroud)

我的查询结果应该是以下实例foo

+----+-----+
| id | baz |
+----+-----+
|  1 |  23 |
|  3 |  45 |
+----+-----+
Run Code Online (Sandbox Code Playgroud)

使用 SQLAlchemy ORM,我尝试过joinouterjoin,但解决方案仍然无法解决。有人告诉我,解决方案很简单,就在我面前......

q = db.session.query(Foo).join(Baz, Baz.foo_id == Foo.id)

q = db.session.query(Foo).outerjoin(Baz, Baz.foo_id == Foo.id)
Run Code Online (Sandbox Code Playgroud)

Art*_*ode 7

您正在寻找的 SQL 查询是这样的:

SELECT foo.* FROM foo LEFT JOIN bar ON bar.foo_id = foo.id WHERE bar.foo_id IS NULL;
Run Code Online (Sandbox Code Playgroud)

LEFT JOIN与 不同INNER JOIN,包括“左”表(即 中指定的表)中的所有FROM tblname,即使它们在“右”表( 中指定的表JOIN tblname)中没有关联的行。这意味着在右表中没有关联行的行将具有NULL值:

foo.id | foo.baz | bar.id | bar.foo_id | bar.zab
-------+---------+--------+------------+--------
     1 |      23 |   NULL |       NULL |    NULL
     2 |      56 |      7 |          2 |      s1
Run Code Online (Sandbox Code Playgroud)

因此,过滤那些NULL在右表的主键中有 a 的行(在任何其他情况下都不能为空,而右表中的其他列可能是),你会得到foo没有关联的bar.

在 SQLAlchemy 中,这变成了这样:

q = db.session.query(Foo).join(Bar, isouter=True).filter(Bar.id == None)
Run Code Online (Sandbox Code Playgroud)

isouter=True对标志join你如何做一个LEFT JOIN有SQLAlchemy的。