【问题标题】:Exclude rows with no associated row in a joined table排除联接表中没有关联行的行
【发布时间】:2018-01-11 22:02:05
【问题描述】:

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

foo:

+----+-----+
| id | baz |
+----+-----+
|  1 |  23 |
|  2 |  56 |
|  3 |  45 |
|  4 |  78 |
+----+-----+

bar:

+-----+--------+-----+
| id  | foo_id | zab |
+-----+--------+-----+
|  7  |      2 | s1  |
|  8  |      4 | s2  |
+-----+--------+-----+

我的查询结果应该是foo 的实例,如下所示:

+----+-----+
| id | baz |
+----+-----+
|  1 |  23 |
|  3 |  45 |
+----+-----+

使用 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)

【问题讨论】:

标签: python sqlalchemy


【解决方案1】:

您要查找的 SQL 查询是这样的:

SELECT foo.* FROM foo LEFT JOIN bar ON bar.foo_id = foo.id WHERE bar.foo_id IS NULL;

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

foo.id | foo.baz | bar.id | bar.foo_id | bar.zab
-------+---------+--------+------------+--------
     1 |      23 |   NULL |       NULL |    NULL
     2 |      56 |      7 |          2 |      s1

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

在 SQLAlchemy 中,变成这样:

q = db.session.query(Foo).join(Bar, isouter=True).filter(Bar.id == None)

joinisouter=True 标志在 SQLAlchemy 中是 how you do a LEFT JOIN

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-27
    • 2011-10-12
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    相关资源
    最近更新 更多