2010-12-05 19 views
19

Tengo una gran tabla PostgreSQL a la que accedo a través de Django. Como el ORM de Django no es compatible con las funciones de ventana, necesito hornear los resultados de una función de ventana en la tabla como una columna regular. Quiero hacer algo como esto:Uso de funciones de ventana en una declaración de actualización

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

Pero consigo ERROR: cannot use window function in UPDATE

¿Puede alguien sugerir un enfoque alternativo? Pasar la sintaxis de la función de ventana a través del método .raw() de Django no es adecuado, ya que devuelve un RawQuerySet, que no admite otras características de ORM como .filter(), que necesito.

Gracias.

Respuesta

34

El error es de postgres no django. Puede volver a escribir esto como:

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; 

O, alternativamente:

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; 

Esto funciona. Acabo de probarlo en postgres-9.6. Aquí está la sintaxis para UPDATE (vea la lista opcional).

Espero que esto ayude.

+0

No creo que necesite la auto-unión? ¡Bien podría estar equivocado, aunque estoy basando esto en lo que funciona en SQL Server! –

+0

@Martin: Usted está seleccionando dos tablas, una es a través de UPDATE 'tablename' y otra está en la cláusula' FROM tablename'. si no se une explícitamente, va a producir un producto cartesiano. – Max

+0

er, ¡No, no lo soy! –

Cuestiones relacionadas