删除一个表中存在而另一个表中不存在的数据?
Posted
技术标签:
【中文标题】删除一个表中存在而另一个表中不存在的数据?【英文标题】:Delete the data which exist in one table and not exist in the other one? 【发布时间】:2013-04-24 07:21:54 【问题描述】:我想选择所有存在于特定表中但不存在于另一个表中的行来删除它们。
我编写了以下查询,但我得到两个表中都存在行!
SELECT UNIQUE b.values_key FROM request_fo a INNER JOIN rm_trans b
ON b.values_key != a.req_year || ',' || a.req_ser
AND b.taskcode = 19
AND b.values_key IS NOT NULL
AND a.req_year IS NOT NULL
AND a.req_ser IS NOT NULL
我想用下面的方法删除request_fo
中存在而rm_trans
中不存在的数据:
DELETE request_fo
FROM request_fo a
INNER JOIN
rm_trans b
ON b.values_key != a.req_year || ',' || a.req_ser
AND b.taskcode = 19
AND b.values_key IS NOT NULL
AND a.req_year IS NOT NULL
AND a.req_ser IS NOT NULL
是这样吗??
【问题讨论】:
不同的 DBMS 对 DELETE 操作有不同的语法,尤其是带有连接操作的 DELETE。您不能自然而然地期望 MS SQL Server 中有效的东西在 Oracle、DB2、Informix、mysql、PostgreSQL 中有效——它通常但不一定在 Sybase 中有效。 @JonathanLeffler:那请问DELETE a FROM request_fo a LEFT JOIN rm_trans b ON b.values_key = a.req_year + ',' + a.req_ser AND b.taskcode = 19 WHERE b.values_key IS NULL;
informix的语法是什么
【参考方案1】:
如果您不能使用连接语法,您也可以使用子选择。
delete from t1
where t1 = something
and not exists
(
select 1
from t2
where t1.key = t2.key
)
【讨论】:
【参考方案2】:当您想要执行此类操作时,您必须进行综合思考。当您需要NOT IN (...)
或NOT EXISTS (...)
时,您正在使用!=
。
您的子句b.values_key != a.req_year || ',' || a.req_ser
将a
中的每一行与b
中的每一行进行比较。在大多数情况下,它们不会等同。但是会有很多示例,其中此特定行中的values_key
与a
的其他行中的a.req_year || ',' || a.req_ser
匹配,而不是当前正在比较的行。这就是为什么返回的数据确实存在于两个表中。
你想尝试这样的事情:
DELETE FROM a
WHERE NOT EXISTS (SELECT 1 FROM b
WHERE b.values_key = a.req_year || ',' || a.req_ser
AND b.task_code = 19)
您还应该将其作为SELECT * FROM a WHERE NOT EXISTS (...)
运行以首先验证它。我会的。
【讨论】:
【参考方案3】:这是执行此操作的 T-SQL 语法:
改用LEFT JOIN
,在WHERE
子句中使用b.values_key IS NULL
谓词,并在DELETE
子句中使用别名a
代替表名:
DELETE a
FROM request_fo a
LEFT JOIN rm_trans b ON b.values_key = a.req_year + ',' + a.req_ser
AND b.taskcode = 19
WHERE b.values_key IS NULL;
在这里查看它的实际效果:
SQL Fiddle Demo。假设req_ser
和req_year
是字符串数据类型,如果它们是整数,则将它们强制转换。
它是如何工作的?
LEFT JOIN
将包括来自LEFT JOIN
左侧的第一个表request_fo
中的那些不匹配的行,即使没有满足JOIN
条件的条目,在这种情况下为values_key
对于那些不匹配的行,值将是 NULL
。
例如,参见this demo,第一个表中的2013 4
在第二个表中不存在,因此它的values_key
将是NULL
,因此添加WHERE b.values_key IS NULL
将为您提供找到的那些在第一个表中,在第二个表中找不到。
【讨论】:
为什么要设置b.values_key IS NULL
?!以上是关于删除一个表中存在而另一个表中不存在的数据?的主要内容,如果未能解决你的问题,请参考以下文章