es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Postgresql: Actualizar columna desde una selección y agregar una condición cuando se devuelven múltiples filas

Básicamente, necesito actualizar una columna utilizando un SELECT, el cual puede devolver más de un valor. Si eso sucede, me gustaría aplicar una segunda condición para determinar cuál de esos valores se debe elegir:

UPDATE train
SET var1 = (
    CASE
        WHEN (SELECT COUNT(*)
              FROM cars
              WHERE (train.var2 LIKE cars.var2))
             > 1)
        THEN (
            SELECT var1
            FROM cars
            WHERE (train.var2 LIKE cars.var2)
              AND cars.var2 in (
                SELECT var2
                FROM cars
                WHERE train.user_id = cars.user_id)
        )
        ELSE (
            SELECT var1
            FROM cars
        WHERE (train.var2 LIKE cars.var2))
        )
    END
);

Creo que lo anterior funciona, pero repito 3 veces el mismo SELECT. ¿Tienes alguna forma de evitar eso? ¿Quizás hay una manera sencilla de capturar cuando el SELECT devuelve más de un valor y hacer algo al respecto?

Gracias.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma de evitar repetir la misma instrucción SELECT varias veces. Puedes usar una Expresión de Tabla Común (CTE, por sus siglas en inglés) para contar primero el número de filas devueltas por la instrucción SELECT y luego usar una instrucción condicional para elegir el valor adecuado para la actualización. Aquí tienes un ejemplo:

    WITH cte AS (
        SELECT var1,
               COUNT(*) OVER () AS cnt
        FROM cars
        WHERE train.var2 LIKE cars.var2
    )
    UPDATE train
    SET var1 = (
        CASE
            WHEN cte.cnt > 1 AND cte.var2 IN (SELECT var2 FROM cars WHERE train.user_id = cars.user_id)
            THEN (SELECT var1 FROM cte WHERE var2 IN (SELECT var2 FROM cars WHERE train.user_id = cars.user_id))
            WHEN cte.cnt > 1
            THEN (SELECT var1 FROM cte LIMIT 1)
            ELSE (SELECT var1 FROM cars WHERE train.var2 LIKE cars.var2)
        END
    );
    

    En este ejemplo, la CTE cuenta primero el número de filas devueltas por la instrucción SELECT e incluye el recuento como una columna en el conjunto de resultados. Este conjunto de resultados se utiliza luego en la instrucción UPDATE con instrucciones condicionales para elegir el valor adecuado para la actualización según el recuento y condiciones adicionales. El uso de una CTE evita repetir la misma instrucción SELECT varias veces y hace que el código sea más conciso y legible.

Comments are closed.