web-dev-qa-db-ja.com

更新ステートメントでのウィンドウ関数の使用

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を返すため、適切ではありません。RawQuerySetは、必要な.filter()などのORM機能をサポートしていません。

ありがとう。

34
jl6

エラーはDjangoではなくpostgresからのものです。これは次のように書き換えることができます。

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を参照)。

お役に立てれば。

55
Max