如何将Oracle SQL IF ELSE插入UPDATE语句?

时间:2017-07-31 17:00:45

标签: sql oracle if-statement

我正在尝试加入3个表,我有以下没有IF ELSE的SQL。

update transaction t
set t.lid= (
select l.id from list l
inner join distance d
on l.ueid=d.ueid
inner join transaction t2
on t2.id=d.id
)

唯一的问题是声明

select l.id from list l
    inner join distance d
    on l.ueid=d.ueid
    inner join transaction t2
    on t2.id=d.id

返回多个值,我无法将其分配给 t.gid 。根据我们的业务规则,如果它返回多个值,我必须将 t.gid 设置为null。如果内部select语句返回多个值,如何在此sql中包含if else语句以返回null?我在网上看过其他帖子,但它们主要是程序或功能。

编辑:

如果 l.id 来自列表表,则基本想法是更新交易表中的所有行只返回一个值(即在内部连接后使用距离表)。如果返回多个值,我将其更新为null。所以我不完全确定我是否应该只使用 t或t2

1 个答案:

答案 0 :(得分:2)

您可以使用a case expression检查每个ID的值的聚合计数:

select t2.id, case when count(l.id) > 1 then null else max(l.id) end as lid
from list l
inner join distance d on l.ueid=d.ueid
inner join transaction t2 on t2.id=d.id
group by t2.id

然后将其用作子查询,与 - 例如 - 两个transaction表中的ID相关联:

update transaction t
set t.lid= (
  select case when count(l.id) > 1 then null else max(l.id) end as lid
  from list l
  inner join distance d on l.ueid=d.ueid
  inner join transaction t2 on t2.id=d.id
  where t2.id = t.id
  group by t2.id
)

使用where t2.id = t.id子句进行关联。虽然如果这是您正在做的检查,您可能根本不想要t2

update transaction t
set t.lid= (
  select case when count(l.id) > 1 then null else max(l.id) end as lid
  from list l
  inner join distance d on l.ueid=d.ueid
  where d.id = t.id
  group by d.id
)

现在与where d.id = t.id相关联。

如果您可能会将相同 value, and in that case still want to use that single repeated value instead of null, then you can add a的多个实例与计数区分开来:

update transaction t
set t.lid= (
  select case when count(distinct l.id) > 1 then null else max(l.id) end as lid
  from list l
  inner join distance d on l.ueid=d.ueid
  where d.id = t.id
  group by d.id
)

未经测试,因为没有可用的样本数据,也没有预期的结果,但希望与您的描述保持一致......

另请注意,如果子查询中没有匹配的值,则会将任何现有的transaction.lid值更新为null - 而不仅仅是在存在多个匹配项时。如果这不是您想要发生的,那么您可以使用exists子句添加过滤器以限制更新哪些行。您也可以使用merge,但update可能仍然更简单,更清晰。