简体   繁体   中英

Add a non-FK condition to a LEFT OUTER JOIN in Django ORM to return rows that don't join

I want to run a query of the type:

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, I want the database to try to join each company to an employee where retired=True , and to return me the companies that fail to join.

This will give me all companies who don't have a retired employee, including those with no employees.

Is there any way of doing this in Django without using .raw()?

I can do the LEFT JOIN with Company.objects.filter(employee__isnull=True) but I can't add the retired join condition, so I get companies with retired employees. I can't make it a Q() , because in the WHERE clause employee.retired will be NULL. I can do:

Company.objects.exclude(id__in=Employee.objects.filter(retired=True).values('company_id'))

Which is equivalent to the less efficient:

SELECT * FROM company WHERE id NOT IN (SELECT company_id FROM employee WHERE retired=True)

Is there a way of achieving the LEFT JOIN in Django?

Or at least changing the second query to a WHERE NOT EXISTS (SELECT 1 FROM employee WHERE company_id=company.id AND retired=True) so we're filtering the sub-query?

I'm using Django 1.8.5, postgres 9.4 and psycopg2 2.6.1

OK, I don't know a better way to achieve this in one shot, because there's no way to tell django to select ALL employees are not retired. If you think your query would work, just use Company.objects.raw() .

Here's my attempt:

no_retired_employees_company = Employee.objects.filter(is_retired=False) \
                                               .values_list('company_id', flat=True).distinct()

no_employee_company = Company.objects.filter(employee__isnull=True) \
                                     .values_list('id', flat=True).distinct()

result = list(a) + list(b)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM