【问题标题】:Django queryset filter - Q() | VS __inDjango 查询集过滤器 - Q() | VS __in
【发布时间】:2015-12-30 11:35:38
【问题描述】:

有什么区别

queryset.filter(Q(foo='bar') | Q(foo='baz'))

queryset.filter(foo__in=['bar', 'baz'])

我发现有时它们会产生不同的结果,我不知道为什么。

我通过这些查询得到了不同的结果:

In [8]: Profile.objects.filter(image="").count()
Out[8]: 7173

In [9]: Profile.objects.filter(image=None).count()
Out[9]: 25946

In [10]: Profile.objects.filter(image__in=["", None]).count()
Out[10]: 7173

In [11]: Profile.objects.filter(Q(image="") | Q(image=None)).count()
Out[11]: 33119

我使用 PostgreSQL 作为我的数据库引擎。

【问题讨论】:

    标签: django filter django-queryset django-orm django-q


    【解决方案1】:

    首先会生成查询:

    SELECT .... FROM ... WHERE (FOO = 'bar' OR FOO = 'baz');
    

    第二个将生成查询:

    SELECT .... FROM ... WHERE (FOO IN ('bar', 'baz'));
    

    两个查询应该计算相同的结果,但可能存在一些性能差异,具体取决于数据库后端。一般来说,使用in应该会更快。

    【讨论】:

    • 你能想出他们给出不同结果的原因吗?
    • 可能是数据库引擎的问题 - SQLite 执行一些比较总是区分大小写和一些总是不区分大小写,MySQL 在这里也有一些差异(您可以在 MySQL 表上设置设置,所以所有比较都将是完成不区分大小写)。除此之外,这里没有不同输出的原因。
    • 根据您的编辑,在 SQL 中 IN 无法与 NULL 值进行比较,因为没有什么等于 null,它是 null 或者不是,并且在许多后端它不会不工作。你应该在这里使用OR 来实现你的结果。
    • 是的,这是我的结论,但我只是想确认一下。
    猜你喜欢
    • 2018-10-20
    • 2021-10-20
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 2020-09-14
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多