0

I have a Query that consists of two DB hits.
which the first contains 'aggregate' - so it perform immediately.
I want to know if I can reduce it to only one DB hit.

The query is:
"Find customers that their id's numbers are bigger than all of texas's customers id's."

The two querysets are:

highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))
res = Customer.objects.filter(id__gt=highest_tx_id['id_max'])

Adding an example:

>>> reset_queries()
>>> highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))
>>> res = Customer.objects.filter(id__gt=highest_tx_id['id__max'])
>>> connection.queries
[{'sql': 'SELECT MAX("customer"."id") AS "id__max" FROM "customer" WHERE "customer"."state" = \'TX\'', 'time': '0.001'}]
>>> res
<QuerySet [<Customer: Customer object (550)>, <Customer: Customer object (551)>, <Customer: Customer object (552)>, <Customer: Customer object (553)>, <Customer: Customer object (555)>, <Customer: Customer object (661)>, <Customer: Customer object (665)>]>
>>> connection.queries
[{'sql': 'SELECT MAX("customer"."id") AS "id__max" FROM "customer" WHERE "customer"."state" = \'TX\'', 'time': '0.001'}, {'sql': 'SELECT "customer"."id", "customer"."fname", "customer"."lname", "customer"."address", "customer"."city", "customer"."state", "customer"."zip_code", "customer"."phone", "customer"."company_name" FROM "customer" WHERE "customer"."id" > 444 LIMIT 21', 'time': '0.001'}]      
>>>

Any way to do these type of queries using 1 DB hit ?

2 Answers 2

1

Building up on @TaipanRex's answer, you can do something like this:

from django.db.models import Subquery

highest_tx_id = Customer.objects.filter(state='TX').order_by('-id').values('id')[:1]
res = Customer.objects.filter(id__gt=Subquery(highest_tx_id))
Sign up to request clarification or add additional context in comments.

Comments

1

You can try using Subquery.

from django.db.models import Subquery
highest_tx_id = Customer.objects.filter(state='TX').aggregate(Max('id'))['id__max']
res = Customer.objects.filter(id__gt=Subquery(highest_tx_id))

1 Comment

Tried something like that. The first query hits the DB (I think because the aggregate). The second query yields an AttributeError: 'int' object has no attribute 'query'..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.