如果子查询返回空,则更新Nullify列

时间:2014-03-24 09:57:16

标签: sql postgresql null sql-update correlated-subquery

我有以下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,但我找不到这样做的方法。

2 个答案:

答案 0 :(得分:2)

如果子查询没有找到任何内容,要将列设置为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 +。

答案 1 :(得分: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;
相关问题