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

Posted

技术标签:

【中文标题】如何将 Oracle SQL IF ELSE 插入到 UPDATE 语句中?【英文标题】:How can I insert Oracle SQL IF ELSE in to UPDATE statement? 【发布时间】:2017-07-31 17:00:44 【问题描述】:

我正在尝试加入 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。如果内部选择语句返回多个值,我如何在此 sql 中合并 if else 语句以返回 null ?我在网上看到过其他帖子,但它们大多是程序或函数。

编辑:

基本思想是如果 l.id 来自 listing 表,则更新 transaction 表上的所有 lid 行仅返回一个值(即与 distance 表进行内部连接后)。如果返回多个值,我必须将其更新为 null。所以我不完全确定我是否应该只使用 t 或 t2

【问题讨论】:

您正在更新的 t 与子查询之间似乎没有任何关联 - 是否需要 t2,如果不是,这是一次性更新还是您应该做的事情真的是在做什么?一些样本数据和预期结果也可能有用。而uid 是保留字,那真的是带引号的标识符吗? @AlexPoole 我更新了我的问题(请参阅编辑)。 uid 是一个错字。它是 ueid。 【参考方案1】:

您可以使用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相关。

如果您可能获得多个相同lidvalue, and in that case still want to use that single repeated value instead of null, then you can add adistinct`的实例到计数:

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 在这里可能更简单明了。

【讨论】:

这对我来说似乎是一个很好的解决方案。自sql运行以来已经30分钟了。我们在事务表上有 100 万行。你有没有办法测试这可能只是 1000 行?谢谢。 您可以使用 where `mod(ID,100000)=0 来测试一组较小的行。您可以通过 mod(id,10000) 轻松增加样本量 ...并通过 mod(id,1000000) 等减少样本量。 @zundarz 更简单的方法是添加“where rownum

以上是关于如何将 Oracle SQL IF ELSE 插入到 UPDATE 语句中?的主要内容,如果未能解决你的问题,请参考以下文章

SQL在If和Else块中插入临时表

在oracle sql语句里有没有if...else...的用法,请各位大侠给个例子看看,灰常感谢!!

oracle报告IF ELSE中的sql查询条件

如何在 SQL 中编写 if else if 条件 |甲骨文 |

ORACLE 中的 PL/SQL、IF-ELSE 或 SELECT DECODE 哪个更好

SQL 用单词 else 替换空的 SQL SELECT 将结果发布到 Oracle