#sql #postgresql #sql-update #subquery #inner-join
#sql #postgresql #sql-обновление #подзапрос #внутреннее соединение
Вопрос:
У меня есть запрос, который может не возвращать результат, что приведет к НУЛЕВОМУ значению
update public.test set geom =
(select geom from public.test where st_geometrytype(geom) = 'X' limit 1)
Я попытался добавить COALESCE для замены на исходное значение, но выдает ошибку
update public.ec_1_eur_1 set geom =
COALESCE(select geom from public.ec_1_eur_1 where
st_geometrytype(geom) = 'X' limit 1, geom)
Также это также выдает ошибку
with s2 as (select geom from public.test where st_geometrytype(geom) = 'X' limit 1)
update public.test set geom = s2 where s2 is not null
Ответ №1:
Я бы использовал здесь синтаксис update / join, поэтому ничего не обновляется, если подзапрос не возвращает строки:
update public.test t
set geom = t1.geom
from (
select geom
from public.test
where st_geometrytype(geom) = 'X'
limit 1
) t1
Что касается запроса, который вы хотели написать, используя coalesce()
: вам нужно было бы заключить подзапрос в круглые скобки, поэтому явно, что он возвращает скаляр:
update public.test t
set geom = coalesce(
(select geom from public.test where st_geometrytype(geom) = 'X' limit 1),
geom
)
Однако этот подход менее эффективен, поскольку он по-прежнему обновляет все строки таблицы до их исходного значения, если подзапрос не возвращает строк; в этом отношении предпочтителен подход update / join.
Обратите внимание, однако, что limit
without order by
имеет мало смысла, поскольку он не является детерминированным; когда подзапрос выдает несколько строк, не определено, какая из них будет выбрана.
Комментарии:
1. Фактический запрос имеет порядок, по которому проверяется область на основе ее пересекающихся геометрий, но я не хотел писать этот сложный запрос для этой проблемы