I have a large PostgreSQL table which I access through Django. Because Django's ORM does not support window functions, I need to bake the results of a window function into the table as a regular column. I want to do something like this:
UPDATE table_name SET col1 = ROW_NUMBER() OVER ( PARTITION BY col2 ORDER BY col3 );
But I get ERROR: cannot use window function in UPDATE
Can anyone suggest an alternative approach? Passing the window function syntax through Django's .raw() method is not suitable, as it returns a RawQuerySet, which does not support further ORM features such as .filter(), which I need.
Thanks.
You can't use the UPDATE statement inside a function unless the UPDATE statement is directed to a table variable local to the function.
If the query executes, the window function supports the CASE Expression . While it is possible to use the CASE Expression in the PARTITION BY clause, I've rarely used it on projects.
Window functions increase the efficiency and reduce the complexity of queries that analyze partitions (windows) of a data set by providing an alternative to more complex SQL concepts, e.g. derived queries. Common use cases include: Ranking results within a specific window (e.g. per-group ranking)
A window function performs a calculation across a set of table rows that are somehow related to the current row. This is comparable to the type of calculation that can be done with an aggregate function.
The error is from postgres not django. You can rewrite this as:
WITH v_table_name AS ( SELECT row_number() over (partition by col2 order by col3) AS rn, primary_key FROM table_name ) UPDATE table_name set table_name.col1 = v_table_name.rn FROM v_table_name WHERE table_name.primary_key = v_table_name.primary_key;
Or alternatively:
UPDATE table_name set table_name.col1 = v_table_name.rn FROM ( SELECT row_number() over (partition by col2 order by col3) AS rn, primary_key FROM table_name ) AS v_table_name WHERE table_name.primary_key = v_table_name.primary_key;
This works. Just tested it on postgres-9.6. Here is the syntax for UPDATE (see the optional fromlist).
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With