Как обменять значение NULL из столбца на последнее значение, отличное от NULL? - PullRequest
0 голосов
/ 27 февраля 2019

Я реализую запрос, который не должен работать без SQLite и PostgreSQL.В моей базе данных есть 2 таблицы, которые я хочу упорядочить по дате, интерполируя значения датчиков.Мои таблицы следующие:

Valor_Sensor_Pressão:

ID_Sensor_Pressão |    Data_Medição    | Valor_Medido
1                  2016-01-01 10:20:05   13
1                  2016-01-01 10:20:06   11
1                  2016-01-01 10:20:12   20
1                  2016-01-01 10:20:13   0
1                  2016-01-01 10:21:05   100

Valor_Sensor_Temperatura:

ID_Sensor_Temperatura |    Data_Medição    | Valor_Medido
1                      2016-01-01 10:20:05   1
1                      2016-01-01 10:20:08   3
1                      2016-01-01 10:20:12   20
1                      2016-01-01 10:21:05   1
1                      2016-01-01 10:21:13   31

Я создал следующий SQL для агрегирования и интерполяции данных по датам:

WITH Resultado (ValorPressão, ValorTemperatura, DataMedida) AS (
    SELECT
        p.Valor_Medido AS pValue,
        t.Valor_Medido AS tValue,
        COALESCE(p.Data_Medição, t.Data_Medição) AS DataMedida
    FROM Valor_Sensor_Pressão AS p
        LEFT JOIN Valor_Sensor_Temperatura AS t USING (Data_Medição)
    WHERE p.ID_Sensor_Pressão = 1
    UNION ALL
    SELECT
        p.Valor_Medido AS pValue,
        t.Valor_Medido AS tValue,
        COALESCE(p.Data_Medição, t.Data_Medição) AS DataMedida
    FROM Valor_Sensor_Temperatura AS t
        LEFT JOIN Valor_Sensor_Pressão AS p USING (Data_Medição)
    WHERE
        p.Data_Medição IS NULL
        AND t.ID_Sensor_Temperatura = 1
    ORDER BY COALESCE(p.Data_Medição, t.Data_Medição)
)

SELECT DataMedida, ValorPressão, ValorTemperatura FROM Resultado

В результате получилось следующее:

"2016-01-01 10:20:05"   "13"    "1"
"2016-01-01 10:20:06"   "11"    NULL
"2016-01-01 10:20:08"   NULL    "3"
"2016-01-01 10:20:12"   "20"    "20"
"2016-01-01 10:20:13"   "0"     NULL
"2016-01-01 10:21:05"   "100"   "1"
"2016-01-01 10:21:13"   NULL    "31"

Я прочитал следующую страницу и адаптировал решение для запроса, который будет использоваться в SQLite.и PostgreSQL:

WITH Resultado (ValorPressão, ValorTemperatura, DataMedida) AS (
    SELECT
        p.Valor_Medido AS pValue,
        t.Valor_Medido AS tValue,
        COALESCE(p.Data_Medição, t.Data_Medição) AS DataMedida
    FROM Valor_Sensor_Pressão AS p
        left join Valor_Sensor_Temperatura t USING (Data_Medição)
    WHERE p.ID_Sensor_Pressão = 1
    UNION ALL
    SELECT
        p.Valor_Medido AS pValue,
        t.Valor_Medido AS tValue,
        COALESCE(p.Data_Medição, t.Data_Medição) AS DataMedida
    FROM Valor_Sensor_Temperatura AS t
        LEFT JOIN Valor_Sensor_Pressão AS p USING (Data_Medição)
    WHERE
        p.Data_Medição IS NULL
        AND t.ID_Sensor_Temperatura = 1
    ORDER BY COALESCE(p.Data_Medição, t.Data_Medição)
)

SELECT
    DataMedida,
    COALESCE(last_value(ValorPressão) OVER (order by DataMedida), 0) AS ValorPressão,
    COALESCE(last_value(ValorTemperatura) over (order by DataMedida), 0) AS ValorTemperatura
FROM Resultado

Я не мог выяснить, в чем заключается ошибка, потому что LAST_VALUE не дал мне предыдущее значение строки, поэтому COALESCE установил 0 вместо предыдущего значения, и я не смогнайти замену IGNORE NULLS для SQLite.

Какие модификации будут возвращать предыдущее значение столбца вместо NULL?Дайте мне что-то вроде этого:

"2016-01-01 10:20:05"   "13"    "1"
"2016-01-01 10:20:06"   "11"    "1"
"2016-01-01 10:20:08"   "11"    "3"
"2016-01-01 10:20:12"   "20"    "20"
"2016-01-01 10:20:13"   "0"     "20"
"2016-01-01 10:21:05"   "100"   "1"
"2016-01-01 10:21:13"   "100    "31"

РЕДАКТИРОВАТЬ: идентификаторы, которые я получу из таблицы других, поэтому я поставил ГДЕ, выбрав "1" только для проверки.

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Я выяснил проблему, я ошибся с LAG и LAST_VALUE.Решением было объединить два последних COALESCE и добавить FIRST_VALUE.

Я добавил новую строку в "Valor_Sensor_Pressão", чтобы проверить, получил ли я NULL в первой строке:

"1" "2016-01-01 10:20:00"   "5.5"

Итак, мой последний запрос:

WITH Resultado (ValorPressão, ValorTemperatura, DataMedida) AS (
    SELECT
        p.Valor_Medido AS pValue,
        t.Valor_Medido AS tValue,
        COALESCE(p.Data_Medição, t.Data_Medição) AS DataMedida
    FROM Valor_Sensor_Pressão AS p
        LEFT JOIN Valor_Sensor_Temperatura t USING (Data_Medição)
    WHERE p.ID_Sensor_Pressão = 1
    UNION ALL
    SELECT
        p.Valor_Medido AS pValue,
        t.Valor_Medido AS tValue,
        COALESCE(p.Data_Medição, t.Data_Medição) AS DataMedida
    FROM Valor_Sensor_Temperatura AS t
        LEFT JOIN Valor_Sensor_Pressão AS p USING (Data_Medição)
    WHERE
        p.Data_Medição IS NULL
        AND t.ID_Sensor_Temperatura = 1
    ORDER BY COALESCE(p.Data_Medição, t.Data_Medição)
)

SELECT
    DataMedida,
    COALESCE(LAST_VALUE(ValorPressão) OVER (ORDER BY DataMedida),LAG(ValorPressão) OVER (ORDER BY DataMedida), FIRST_VALUE(ValorPressão) OVER (ORDER BY DataMedida),0) AS ValorPressão,
    COALESCE(LAST_VALUE(ValorTemperatura) OVER (ORDER BY DataMedida), LAG(ValorTemperatura) OVER (ORDER BY DataMedida), FIRST_VALUE(ValorTemperatura) OVER (ORDER BY DataMedida),0) AS ValorTemperatura
FROM Resultado

И мой результат:

"2016-01-01 10:20:00"   "5.5"   "0"
"2016-01-01 10:20:05"   "13"    "1"
"2016-01-01 10:20:06"   "11"    "1"
"2016-01-01 10:20:08"   "11"    "3"
"2016-01-01 10:20:12"   "20"    "20"
"2016-01-01 10:20:13"   "0"     "20"
"2016-01-01 10:21:05"   "100"   "1"
"2016-01-01 10:21:13"   "100"   "31"
0 голосов
/ 27 февраля 2019

Вы можете реализовать свой текущий запрос более просто:

select id, data, Valor_Medido, valor_temperatura
from (select ID_Sensor_Pressã as id, Data_Medição as data, Valor_Medido, null as valor_temperatura
      from valor_Sensor_Pressão
      union all
      select ID_Sensor_Temperatura, Data_Medição, null, Valor_Medido
      from Valor_Sensor_Temperatura
     ) v
group by id, data;

Тогда то, что вы хотите сделать, легче сделать в Postgres с помощью оконных функций.Но для общего решения вы можете использовать подзапросы:

with v as (
      select id, data, max(Valor_Medido) as Valor_Medido, max(valor_temperatura) as valor_temperatura
      from (select ID_Sensor_Pressã as id, Data_Medição as data, Valor_Medido, null as valor_temperatura
            from valor_Sensor_Pressão
            union all
            select ID_Sensor_Temperatura, Data_Medição, null, Valor_Medido
            from Valor_Sensor_Temperatura
           ) v
      group by id, data
     )
select v.*,
       coalesce(Valor_Medido,
                (select v2.Valor_Medido
                 from v v2
                 where v2.id = v.id and v2.data < v.data
                 order by v2.data desc
                 limit 1
                )
               ) as valor_medido,
       coalesce(valor_temperatura,
                (select v2.valor_temperatura
                 from v v2
                 where v2.id = v.id and v2.data < v.data
                 order by v2.data desc
                 limit 1
                )
               ) as valor_temperatura,
from v;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...