Как настроить обновление поля строки со значением ближайшего к ней по дате другого поля? - PullRequest
0 голосов
/ 27 декабря 2018

У меня огромная таблица с 2м + строками.Структура выглядит следующим образом:

ThingName (STRING),
Date (DATE),
Value (INT64)

Иногда Value равен null, и мне нужно исправить это, установив для него значение NOT NULL Value, ближайшего к нему с помощью Date строка, соответствующая ThingName ...

И я совершенно не SQL-парень.

Я попытался описать свою задачу с помощью этого запроса (и упростил ее, используя только предыдущиедаты (но на самом деле мне нужно проверить и будущие даты)):

update my_tbl as SDP
set SDP.Value = (select SDPI.Value
    from my_tbl as SDPI
    where SDPI.Date < SDP.Date
    and SDP.ThingName = SDPI.ThingName
    and SDPI.Value is not null
    order by SDPI.Date desc limit 1)
where SDP.Value is null;

Там я пытаюсь установить строку обновления Value с той, которую я выбираю из той же таблицы для той же ThingName и с limit 1 Я оставляю только один результат.

Но редактор запросов говорит мне следующее: Correlated subqueries that reference other tables are not supported unless they can be de-correlated, such as by transforming them into an efficient JOIN.

На самом деле, я совсем не уверен, что мою задачу можно решить только с помощью запроса.

Так, кто-нибудь может мне помочь?Если это невозможно, то скажите мне, если возможно, скажите, какие конструкции SQL могут мне помочь.

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Ниже для BigQuery Standard SQL

Во многих (если не в большинстве) случаях вы не хотите обновлять таблицу (так как это связано с дополнительными затратами и ограничениями связан с операторами DML ), но может корректировать «пропущенные» значения в запросе - как в следующем примере:

#standardSQL
SELECT 
  ThingName, 
  date, 
  IFNULL(value, 
    LAST_VALUE(value IGNORE NULLS) 
    OVER(PARTITION BY thingname ORDER BY date)
  ) AS value
FROM `project.dataset.my_tbl`

Если по какой-то причине вам действительно нужно обновить таблицу- Вышеприведенное утверждение не поможет, так как ОБНОВЛЕНИЕ DML не позволяет использовать аналитические функции, поэтому вам нужно использовать другой подходНапример, как показано ниже, один

#standardSQL
SELECT 
  t1.ThingName, t1.date, 
  ARRAY_AGG(t2.Value IGNORE NULLS ORDER BY t2.date DESC LIMIT 1)[OFFSET(0)] AS value
FROM `project.dataset.my_tbl` AS t1
LEFT JOIN `project.dataset.my_tbl` AS t2
ON t2.ThingName = t1.ThingName
AND t2.date <= t1.date
GROUP BY t1.ThingName, t1.date, t1.value

, и теперь вы можете использовать его для обновления таблицы, как в примере ниже

#standardSQL
UPDATE `project.dataset.my_tbl` t
SET value = new_value
FROM (
  SELECT TO_JSON_STRING(t1) AS id, 
    ARRAY_AGG(t2.Value IGNORE NULLS ORDER BY t2.date DESC LIMIT 1)[OFFSET(0)] new_value
  FROM `project.dataset.my_tbl` AS t1
  LEFT JOIN `project.dataset.my_tbl` AS t2
  ON t2.ThingName = t1.ThingName
  AND t2.date <= t1.date 
  GROUP BY id
)
WHERE TO_JSON_STRING(t) = id   
0 голосов
/ 27 декабря 2018

В BigQuery update довольно редко.Кажется, вам нужна логика:

select t.*,
       coalesce(value,
                lag(value ignore nulls) over (partition by thingname order by date)
               ) as value
from my_tbl;

Я не вижу смысла сохранять это обратно в таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...