【发布时间】:2024-04-17 14:35:01
【问题描述】:
我想运行以下类型的查询:
SELECT company.id
FROM company
LEFT OUTER JOIN employee
ON company.id=employee.company_id AND employee.retired=True
WHERE employee.id IS NULL
IE,我希望数据库尝试将每个公司加入到退休=True 的员工,并将未能加入的公司返回给我。
这将给我所有没有退休员工的公司,包括那些没有员工的公司。
在 Django 中有什么方法可以在不使用 .raw() 的情况下做到这一点?
我可以使用 Company.objects.filter(employee__isnull=True) 进行 LEFT JOIN,但我无法添加 retired 加入条件,因此我会找到有退休员工的公司。我不能将其设为Q(),因为在WHERE 子句中,employee.retired 将为NULL。我能做到:
Company.objects.exclude(id__in=Employee.objects.filter(retired=True).values('company_id'))
相当于效率较低的:
SELECT * FROM company WHERE id NOT IN (SELECT company_id FROM employee WHERE retired=True)
有没有办法在 Django 中实现 LEFT JOIN?
或者至少将第二个查询更改为WHERE NOT EXISTS (SELECT 1 FROM employee WHERE company_id=company.id AND retired=True),以便我们过滤子查询?
我正在使用 Django 1.8.5、postgres 9.4 和 psycopg2 2.6.1
【问题讨论】:
-
您是使用 django 从头开始构建数据库,还是使用旧数据库?因为如果您使用的是 django,那么在
id中有一个 null 的员工是没有意义的。此外,最好发布您的模型,以便我们更好地了解您的数据库。 -
感谢尚,数据库是使用 Django 从头开始构建的,没有员工记录具有空 id - 这正是我检测到左连接没有设法找到满足连接的员工记录的方式标准。这些模型要复杂得多,所以我创建了这个简化的示例来解释我的要求。
-
所以
Employee模型有一个公司的外键,对吧? -
是的,非常感谢,它有两个字段 -
company_id是公司的外键,retired是布尔值。 SQL 查询和 Django ORM 代码都返回相同的行:所有没有退休员工的公司,包括根本没有员工的公司。只是第一次查询效率更高。
标签: python django orm left-join