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.

Teradata: Suma consecutiva de columnas a partir del registro actual y comparar el resultado con una columna diferente.

Registros de origen:

Product_id Date Qty1 Qty2
XXXX 22-12-2021 1000 250
XXXX 23-12-2021 200 50
XXXX 24-12-2021 1400 400
XXXX 25-12-2021 300 900
XXXX 26-12-2021 1800 600
XXXX 27-12-2021 900 450
YYYY 22-12-2021 30 350
YYYY 23-12-2021 10 20
YYYY 24-12-2021 70 10
YYYY 25-12-2021 80 80

Para cada product_id, date y Qty1, me gustaría comparar Qty1 con la suma consecutiva de Qty2 cuando se alcanza Qty1 < sum(Qty2). Contar el número de Qty2’s – 1 para llenar la columna “Qty Disponible para Días”.

Por ejemplo:
Cálculo del Registro 1: para el product_id XXXX, la fecha es 22/12/2021 y Qty1 es 1000.
Hacer la suma de los registros siguientes en la columna Qty2 hasta que se alcance un valor mayor que Qty1 para ese registro.
Qty1 es menor que Suma(250+50+400+900)
Para este registro, el número de Qty2 necesarios para alcanzar Qty1 es menor que Sum(Qty2) es de 4 valores, por lo que me gustaría completar 4-1=3 en “Qty Disponible para Días”.

Cálculo del Registro 2: para el product_id XXXX, la fecha es 23/12/2021 y Qty1 es 200.
Hacer la suma de los registros siguientes en la columna Qty2 hasta que se alcance un valor mayor que Qty1 para ese registro.
Qty1 es menor que Suma(50+400)
Para este registro, el número de Qty2 necesarios para alcanzar Qty1 es menor que Sum(Qty2) es de 2 valores, por lo que me gustaría completar 2-1=1 en “Qty Disponible para Días”.

Resultado deseado:

Product_id Date Qty1 Qty2 Qty Disponible para Días
XXXX 22-12-2021 1000 250 3
XXXX 23-12-2021 200 50 1
XXXX 24-12-2021 1400 400 2
XXXX 25-12-2021 300 900 0
XXXX 26-12-2021 1800 600 2
XXXX 27-12-2021 900 450 1
YYYY 22-12-2021 30 350 0
YYYY 23-12-2021 10 20 0
YYYY 24-12-2021 70 10 1
YYYY 25-12-2021 80 80 1

Cualquier ayuda para resolver esto en SQL de Teradata será de gran ayuda. Gracias de antemano.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución SQL de Teradata para calcular “Cantidad disponible para días”

    CON recursiva cte AS (
      SELECT 
        product_id, 
        fecha, 
        qty1, 
        qty2, 
        CASE WHEN SUM(qty2) OVER (
          PARTITION BY product_id 
          ORDER BY fecha 
          ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
        ) < qty1 THEN 1 ELSE 0 END AS flag 
      FROM source_records
    ), 
    cte2 AS (
      SELECT 
        product_id, 
        fecha, 
        qty1, 
        qty2,
        SUM(flag) OVER (
          PARTITION BY product_id 
          ORDER BY fecha 
          ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
        ) AS dias_disponibles
      FROM cte
    )
    SELECT 
      product_id, 
      fecha, 
      qty1, 
      qty2, 
      CASE 
        WHEN dias_disponibles = 0 THEN 0 
        ELSE LEAST((dias_disponibles - flag) + 1, SUM(flag) OVER (
          PARTITION BY product_id 
          ORDER BY fecha 
          ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
        )) - 1 
      END AS cant_disponible_por_dias 
    FROM cte2
    

    Explicación:

    • Primero, necesitamos calcular una bandera que indique cuándo la suma de los valores qty2 consecutivos supera qty1. Para esto, utilizamos una expresión de tabla común recursiva (CTE). En la CTE, calculamos la columna de bandera utilizando la función de ventana SUM con la especificación del marco ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING para obtener la suma de los valores qty2 desde la fila actual hasta el final de la partición. Comparamos la suma con qty1 y establecemos la bandera en 1 si la suma es menor que qty1, de lo contrario, en 0.
    • Luego, utilizamos otra CTE (cte2) para calcular la cantidad de días durante los cuales cada producto tiene suficientes valores qty2 para cumplir con su requerimiento de qty1. Utilizamos la función de ventana SUM con la especificación del marco ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING en la columna de bandera para obtener la suma acumulada de banderas desde la fila actual hasta el final de la partición.
    • Finalmente, utilizamos las columnas qty1, qty2 y bandera de la primera CTE, y la columna de días_disponibles de la segunda CTE, para calcular la columna cant_disponible_por_dias en la instrucción SELECT más externa. Utilizamos una expresión CASE para manejar el caso en el que el producto no tenga valores qty2 disponibles para ningún día. En este caso, establecemos cant_disponible_por_dias en 0. Para otros casos, calculamos cant_disponible_por_dias como (dias_disponibles – flag) + 1, sin exceder la suma de banderas desde la fila actual hasta el final de la partición menos 1. Utilizamos la función LEAST para manejar esta condición.

Comments are closed.