Django - 查询集和一般 SQL 问题

发布于 2024-11-15 06:36:05 字数 422 浏览 1 评论 0原文

首先,给定一个模型 Foo 且它的 m2m 指向 Bar,以下查询如何工作(当没有任何内容是 NULL< /code> 本身(连接和第一部分被省略):

>> print Foo.objects.get(bar__isnull=True).query
...WHERE "barapp_bar"."id" IS NULL

空的东西让我对相关 m2m 的过滤感到困惑

其次,有没有办法让这个类似的查询在处理大量数据时更快。行数:

Foo.objects.get(bar__in=[bar1, bar2, bar3, bar4])

Firstly, given a model Foo and it's m2m pointing to Bar, how does the following query work (when nothing really is NULL per se (join and first part ommited):

>> print Foo.objects.get(bar__isnull=True).query
...WHERE "barapp_bar"."id" IS NULL

The null stuff throws me off with regards to filtering by related m2m.

Secondly, is there a way to make this similar query faster when dealing with lots of rows:

Foo.objects.get(bar__in=[bar1, bar2, bar3, bar4])

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酷炫老祖宗 2024-11-22 06:36:05

省略的连接很重要。如果您查看完整的查询,您将看到 Django 执行两个左外连接< /a> 从 foo 表到连接表 foo_barbar 表。

考虑两个 foos 和两个 bars。令 foo_1bar_1bar_2 相关,并且 foo_2 不与任何 bars.

下面的查询有两个左外连接,每个 foo 至少包含一次,并且 NULL 将出现在 foo_2 的 bar 列中,该列与任何 bars 都不相关

SELECT foo.id as foo_id, bar.id as bar_id 
FROM foo LEFT OUTER JOIN foo_bar 
  ON foo_id = foo_bar.foo_id
LEFT OUTER JOIN bar
  ON foo_bar.bar_id = bar.id;
+--------+--------+
| foo_id | bar_id | 
+--------+--------+
| 1      | 1      |
| 1      | 2      |
| 2      | NULL   |
+--------+--------+

Foo.objects.get(bar__isnull=True) 的查询与此类似,但它不会从 bar 表中选择任何内容,而是根据 bar.id 进行过滤> 是 NULL,因为我们只想要与任何 bars 无关的 foos

SELECT foo.id as foo_id 
FROM foo LEFT OUTER JOIN foo_bar 
  ON foo_id = foo_bar.foo_id
LEFT OUTER JOIN bar
  ON foo_bar.bar_id = bar.id
where bar_id is NULL;
+--------+
| foo_id | 
+--------+
| 2      |
+--------+

The ommitted joins are important. If you look at the full query, you will see that Django does two Left Outer Joins from the foo table to the joining table foo_bar and to the bar table.

Consider two foos and two bars. Let foo_1 be related to bar_1 and bar_2, and foo_2 not be related to any bars.

The query below with two left outer joins with include every foo at least once, and NULL will appear in the bar column for foo_2 which is not related to any bars.

SELECT foo.id as foo_id, bar.id as bar_id 
FROM foo LEFT OUTER JOIN foo_bar 
  ON foo_id = foo_bar.foo_id
LEFT OUTER JOIN bar
  ON foo_bar.bar_id = bar.id;
+--------+--------+
| foo_id | bar_id | 
+--------+--------+
| 1      | 1      |
| 1      | 2      |
| 2      | NULL   |
+--------+--------+

The query for Foo.objects.get(bar__isnull=True) is similar to this, but it doesn't select anything from the bar table, and it filter on bar.id is NULL, because we only want the foos which are not related to any bars.

SELECT foo.id as foo_id 
FROM foo LEFT OUTER JOIN foo_bar 
  ON foo_id = foo_bar.foo_id
LEFT OUTER JOIN bar
  ON foo_bar.bar_id = bar.id
where bar_id is NULL;
+--------+
| foo_id | 
+--------+
| 2      |
+--------+
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文