将这两条 SQL 语句合二为一

Posted

技术标签:

【中文标题】将这两条 SQL 语句合二为一【英文标题】:Combine these two SQL statements into one 【发布时间】:2019-10-26 10:51:39 【问题描述】:

我有两个表 t1t2 和列 name, invoice, total

我正在使用此查询来获取 T2 中而不是 T1 中的行

select * 
from t2  
where name = (select source from info) 
except 
(select * from t1)

它工作正常并返回几行,我想要的是在一个语句中删除这些返回的行。

我已经尝试过了,但它会删除 T2 中的所有行,而不仅仅是从查询中返回的行。

delete from t2 
where exists ((select * 
               from t2  
               where name = (select source from info) 
               except 
               (select * from t1) 
             )) 

这是我的数据示例:

T1

T2

返回的数据(存在于 T2 中,而不存在于名称为 C2 的 T1 中)

第三个表信息是获取名称,在这种情况下是 C2。

提前致谢。

【问题讨论】:

从两个表中添加一些示例数据,然后说明您要删除哪些行。同时标记适当的数据库名称。 您说您有两个表,但您的查询引用了三个。 CHECK MY UPDATE,第三张表是获取本地客户端的名字 【参考方案1】:

您可以通过t2t1 的左连接来做到这一点:

delete t
from (
  select * from t2
  where name = (select source from info)
) t left join t1
on t1.name = t.name and t1.invoice = t.invoice and t1.total = t.total
where t1.name is null

见demo。 如果你想使用NOT EXISTS

delete t
from (
  select * from t2
  where name = (select source from info)
) t 
where not exists (
  select 1 from t1
  where name = t.name and invoice = t.invoice and total = t.total
)

见demo。 结果(t2 中剩余的行):

> name | invoice | total
> :--- | ------: | ----:
> C1   |       1 |   150
> C1   |       2 |   300
> C2   |       1 |   200
> C2   |       2 |   165

【讨论】:

我真的很感激,第一个答案完全符合我的要求,非常感谢,只是一个问题,我们为什么使用(其中 t1.name 为空)你能解释一下吗?再次感谢。 这是 t2 到 t1 的左连接。如果 t1 的任何行与 t1 的任何行都不匹配,则 t1.name 的值和该行中的其他列将为空。这是检查没有匹配项的方法,这就是您想要的。删除 t2 中与 t1 中的行不匹配的行。【参考方案2】:

我正在使用此查询来获取 T2 中而不是 T1 中的行

我会使用的查询是:

select t2.*
from t2
where not exists (select 1 from t1 where t1.? = t2.name);

不清楚t1中匹配列的名称是什么。

这很容易变成delete

delete from t2
where not exists (select 1 from t1 where t1.? = t2.name);

【讨论】:

【参考方案3】:

你想从 t2 中删除,有两个条件:

name =(从信息中选择来源) 行在 t1 中没有匹配项

声明:

delete from t2
where name = (select source from info)
and not exists
(
  select *
  from t1
  where t1.name = t2.name
    and t1.invoice = t2.invoice
    and t1.total = t2.total
);

或使用IN 子句缩短,仅在允许IN 使用元组的DBMS 中可用:

delete from t2
where name = (select source from info)
and (name, invoice, total) not in (select name, invoice, total from t1);

【讨论】:

以上是关于将这两条 SQL 语句合二为一的主要内容,如果未能解决你的问题,请参考以下文章

将两条SQL语句合二为一,满足一定条件时更新表中的一行

这两条sql语句有啥区别[重复]

plsql动态sql语句[重复]

你如何加入两个计算的sql语句?

mysql sql语句两条合并成一条

oracle sql语句获取前两条数据