selectsubquerycasewhere-clausedenodo

Create View for Latest Value Each Day (No Skipped Days)


I have a table that records the firmware version for each device every day. If a device goes down, the script to populate the device's firmware won't be able to reach it for a value so there is no record for offline days. I need a view that will return the latest firmware version for each device every day, regardless if the device was down or not. This works great in Postgres SQL:

SELECT
    d.ip,
    d.date,
    CASE
        WHEN f.firmware_version IS NOT NULL THEN f.firmware_version
        ELSE (--Use last available firmware_version for the device:
            SELECT l.firmware_version
            FROM firmware l
            WHERE l.date < d.date AND l.firmware_version IS NOT NULL
            ORDER BY l.date DESC
            LIMIT 1)
        END AS firmware_version
FROM
    devices d --Table with a record for every device every day
    LEFT JOIN firmware f ON d.date = f.date AND d.ip = f.ip

However, we are transitioning to Denodo, and I cannot get this query to work in Denodo. It seems to fail with the subquery in the case statement. Does anyone know how I can get logic like this to create a view in Denodo?


Solution

  • I figured it out! It's a bit long and complicated, but it works just the way I hoped. Here is the solution if it helps anyone else:

    --Get all values of firmware prior to the listed date
    --Note: Will need to find the latest firmware for each date in a later step
    WITH firmware_prep (
        ip,
        date_main,
        date_firmware,
        firmware
    ) AS (
        SELECT
            d.ip,
            d.date,
            f.date,
            f.firmware
        FROM
            device d LEFT JOIN
            firmware f ON (d.ip = f.ip AND f.date <= d.date AND f.firmware IS NOT NULL) 
    )
    
    SELECT
        s.ip,
        s.date_main AS date,
        f.firmware
    FROM
        (--Here's where you find which firmware date is the latest available date for each listed date:
            SELECT
                ip,
                date_main,
                MAX(date_firmware) AS select_date
            FROM
                firmware_prep
            GROUP BY
                ip,
                date_main
        ) s LEFT JOIN
        firmware f ON s.select_date = f.date AND s.ip = f.ip