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.

Seleccione 1 fila para cada día entre la fecha de inicio y la fecha de finalización en SQL DB2.

Tenemos una tabla antigua de legado con nuestro sistema de puntos que se ve así:

desde fecha hasta fecha puntos lunes puntos martes puntos miércoles puntos jueves puntos viernes
6-12-2021 10-12-2021 10 30 20 15 5
13-12-2021 13-12-2021 10 0 0 0 0

Ahora, para Power BI y nuestro análisis, queremos crear una consulta SELECT que produzca un resultado como este:

fecha puntos
6-12-2021 10
7-12-2021 30
8-12-2021 20
9-12-2021 15
10-12-2021 5
13-12-2021 10

¿Cómo se puede lograr algo así en DB2?

¡Gracias de antemano por la ayuda!

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para lograr esto en DB2, puedes utilizar el operador UNPIVOT para transformar la tabla de un formato amplio a un formato estrecho. Luego, puedes usar una combinación del operador BETWEEN y la función COALESCE para rellenar cualquier valor faltante con cero.

    Aquí hay una consulta de ejemplo que debería lograr el resultado deseado:

    SELECT d.date, COALESCE(p.points, 0) AS points
    FROM (
        SELECT from_date AS start, until_date AS end
        FROM legacy_table
        UNION
        SELECT MAX(until_date) + 1 DAY, DATE('9999-12-31')
        FROM legacy_table
    ) AS r (start, end)
    CROSS JOIN (
        SELECT DATE('2021-12-06') + num DAYS AS date
        FROM (
            SELECT ROW_NUMBER() OVER() - 1 AS num
            FROM sysibm.sysdummy1
            FETCH FIRST 100 ROWS ONLY
        ) AS nums
    ) AS d
    LEFT JOIN (
        SELECT from_date, points monday, points tuesday, points wednesday, points thursday, points friday
        FROM legacy_table
    ) AS p
    ON d.date BETWEEN p.from_date AND p.until_date
          AND (
            DAYNAME(d.date) = 'Monday' AND p.monday IS NOT NULL OR
            DAYNAME(d.date) = 'Tuesday' AND p.tuesday IS NOT NULL OR
            DAYNAME(d.date) = 'Wednesday' AND p.wednesday IS NOT NULL OR
            DAYNAME(d.date) = 'Thursday' AND p.thursday IS NOT NULL OR
            DAYNAME(d.date) = 'Friday' AND p.friday IS NOT NULL
          )
          AND (
            DAYNAME(d.date) = 'Monday' AND p.monday OR
            DAYNAME(d.date) = 'Tuesday' AND p.tuesday OR
            DAYNAME(d.date) = 'Wednesday' AND p.wednesday OR
            DAYNAME(d.date) = 'Thursday' AND p.thursday OR
            DAYNAME(d.date) = 'Friday' AND p.friday
          )
    WHERE d.date BETWEEN '2021-12-06' AND '2021-12-13'
    ORDER BY d.date
    

    La consulta primero crea una tabla de rangos de fechas al unir los rangos de fechas existentes en la tabla heredada con una fila que representa todas las fechas futuras. Luego genera una tabla de fechas individuales usando una unión cruzada con una secuencia de números.

    La unión izquierda con la tabla heredada se realiza luego uniéndose a fechas que caen dentro de un rango dado y que coinciden con el día de la semana correspondiente. La función COALESCE se utiliza para rellenar cualquier punto faltante con ceros.

    Finalmente, el conjunto de resultados se limita al rango de fechas deseado y se ordena por fecha.

    Nota que esta consulta asume que los valores en la tabla heredada son inclusivos de ambas fechas de inicio y fin. Si no lo son, es posible que debas ajustar el operador BETWEEN en consecuencia.

Comments are closed.