Django raw() query, calculated field in WHERE clause
Asked Answered
T

2

2

I'm wondering if there are any limitations on syntax of raw() method when using calculated fields. Here is a quick example:

Company.objects.raw('''SELECT *,core_location.a + core_location.b as dist
FROM core_location,core_company  
ORDER BY dist''')

The above code works as expected (the results are sorted by calculated field 'dist'), but when I add WHERE clause, for example:

Company.objects.raw('''SELECT *,core_location.a + core_location.b as dist
FROM core_location,core_company
WHERE dist<10  
ORDER BY dist''')

i'm getting (1054, "Unknown column 'dist' in 'where clause'")

So far it looks like I cannot use calculated field in WHERE clause, but I can use it in ORDER BY statement. Please share your experience. Thank you.

Tittivate answered 16/3, 2011 at 23:40 Comment(1)
None of this is actually Django save for the calling mechanism. You're getting a MySQL error.Oligochaete
B
7

It actually has nothing to do with Django itself, but with the way MySQL works.

You can't use aliases in WHERE conditions, because WHERE clause evaluation precedes the aliases evaluation.

You can either:

  • Repeat the clause:

    Company.objects.raw('''SELECT *,core_location.a + core_location.b as dist
    FROM core_location,core_company
    WHERE (core_location.a + core_location.b)<10    
    ORDER BY dist''')
    
  • Do a subselect:

    Company.objects.raw('''SELECT * FROM (
        SELECT *,core_location.a + core_location.b as dist
        FROM core_location,core_company            
    ) as subselect
    WHERE dist<10  
    ORDER BY dist''')
    
Bergschrund answered 17/3, 2011 at 1:33 Comment(0)
B
4

You can use the HAVING clause for derived columns. BTW - this includes columns which are aggregations e.g. the result of SUM, COUNT etc.

So, the following should work:

Company.objects.raw('''SELECT *,core_location.a + core_location.b as dist
FROM core_location,core_company
HAVING dist<10  
ORDER BY dist''')
Belay answered 2/2, 2012 at 8:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.