在更新语句中使用窗口函数

jl6*_*jl6 32 sql django postgresql window-functions

我有一个大的PostgreSQL表,我可以通过Django访问.因为Django的ORM不支持窗口函数,所以我需要将窗口函数的结果作为常规列烘焙到表中.我想做这样的事情:

UPDATE  table_name
SET     col1 = ROW_NUMBER() OVER ( PARTITION BY col2 ORDER BY col3 );
Run Code Online (Sandbox Code Playgroud)

但我明白了 ERROR: cannot use window function in UPDATE

任何人都可以提出替代方法吗?通过Django的.raw()方法传递窗口函数语法是不合适的,因为它返回一个RawQuerySet,它不支持我需要的其他ORM功能,如.filter().

谢谢.

Max*_*Max 50

错误来自postgres而不是django.您可以将其重写为:

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;  
Run Code Online (Sandbox Code Playgroud)

或者:

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;
Run Code Online (Sandbox Code Playgroud)

这有效.刚刚在postgres-9.6上测试过它.以下是UPDATE的语法(请参阅可选的fromlist).

希望这可以帮助.

  • 我需要从`SET`语句中省略`table_name.部分,否则这很有用. (2认同)