46

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

UPDATE  table_name
SET     col1 = ROW_NUMBER() OVER ( PARTITION BY col2 ORDER BY col3 );

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

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

谢谢。

4

1 回答 1

77

错误来自 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;  

或者:

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;

这行得通。刚刚在 postgres-9.6 上测试过。这是UPDATE的语法(请参阅可选的fromlist)。

希望这可以帮助。

于 2010-12-05T14:57:33.883 回答