[英]Nullify column in update if subquery returns empty
我有以下SQL
查詢
UPDATE container SET member_containers = members
FROM
(
SELECT inter_container_membership.owning_container_id AS owner_cont
,array_to_string(array_agg(inter_container_membership.member_container_id),',') AS members
FROM inter_container_membership
GROUP BY inter_container_membership.owning_container_id) v
WHERE container.id = owner_cont;
問題是,如果sub-query
不返回任何內容,則member_containers
將不會更新,如果是這種情況,我需要設置為 null,我嘗試使用EXISTS
子句但它沒有用。
UPDATE container SET member_containers =
CASE WHEN EXISTS (
SELECT * FROM inter_container_membership
WHERE container.id = inter_container_membership.owning_container_id
) THEN members
ELSE NULL END
FROM (
SELECT inter_container_membership.owning_container_id AS owner_cont
,array_to_string(array_agg(inter_container_membership.member_container_id),',') AS members
FROM inter_container_membership
GROUP BY inter_container_membership.owning_container_id) v
WHERE container.id = owner_cont;
所以現在我想在更新之前取消member_containers
,但我找不到這樣做的方法。
要在子查詢未找到任何內容的情況下將列設置為 NULL,您可以使用相關子查詢而不是連接:
UPDATE container c
SET member_containers = (
SELECT string_agg(member_container_id, ',')
FROM inter_container_membership i
WHERE i.owning_container_id = c.id
GROUP BY owning_container_id
);
通常,這種查詢是錯誤的,因為如果未找到任何內容,則不應取消該列。 但你似乎正是想要那個。
此外,相關子查詢往往很慢。 考慮添加這個左連接(做同樣的事情):
UPDATE container c
SET member_containers = i.members
FROM container c1
LEFT JOIN (
SELECT owning_container_id
, string_agg(member_container_id, ',') AS members
FROM inter_container_membership
GROUP BY 1
) i ON i.owning_container_id = c1.id
WHERE c.id = c1.id;
還使用string_agg()
而不是array_to_string(array_agg(...))
。 需要 Postgres 9.0+。
使用 CTE:
WITH m AS (
SELECT icm.owning_container_id AS owner_cont,
array_to_string(array_agg(icm.member_container_id),',') AS members
FROM inter_container_membership icm
GROUP BY icm.owning_container_id)
UPDATE container SET member_containers = m.members
WHERE id = m.owner_cont;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.