sql not in问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql not in问题相关的知识,希望对你有一定的参考价值。

access数据库文件只有一个表A,有60000多条记录
结构如下:
ID 地址 地区
1 厦门 华东
2 泉州 华东
3 厦门 华东
4 深圳 华南
5 深圳 华南
6 厦门 华东
.....................
因为存在重复记录,比如 ID:1,3,4,5
所以使用以下语句执行删除重复的记录,保留一条,但发现 NOT IN 的效率很慢,居然要等上10多分钟,怎办?有没有更好的办法

delete from cidz where id NOT in (select max(id) from cidz group by 地址)

NOT IN速度当然很慢,因为这样会存在两个全表检索的情况,使用NOT EXISTS会快很多。
delete from t_b where exists (select 1 from t_b a where isnull(a.cost,0) > isnull(t_b.cost,0) and a.cost <> t_b.cost)
DELETE FROM CIDZ WHERE EXISTS (SELECT 1 FROM CIDZ A WHERE A.ID > CIDZ.ID)
---------这个删除之后,会只剩下这个表中ID最大的一行,没有别的连接条件了么?如果这么已删除,表中只剩下一行了,我觉得你的意思是不是只留下每个地址分组后ID最大的一行啊?
参考技术A 这个效率肯定是很慢的,因为不单单是not in效率较低,group by效率也高不到哪儿去!

这种情况可以看出是由于设计表时进行了错误的分析,导致出现了大量的冗余。
id->地址.id->地区,地址->地区
这是函数依赖关系,也就是说如果id是主键的情况下,存在者有属性对非主属性的依赖,这张表不符合2NF,所以会出现大量的冗余,而这个才是效率低下的真正原因!也就是说你的语句上的只是效率问题,而数据库才是执行慢的真正原因!如果合理的数据库,存在1K左右的记录,就算你还使用group by与not in也不会等到10分钟的!

SQL NOT IN 函数

【中文标题】SQL NOT IN 函数【英文标题】:SQL NOT IN Function 【发布时间】:2012-01-07 16:56:58 【问题描述】:

我正在尝试插入一条记录,我想检查它是否已存在于表中。

我试试

INSERT INTO emp (empno, name) 
VALUES(2, 'ram') 
WHERE empno NOT IN (select empno from emp);

但它显示错误'incorrect syntax near where'

【问题讨论】:

你使用的是什么 SQL 服务器? 【参考方案1】:

您可以使用以下查询将记录插入到 emp 如果您一次插入一条记录,那么以下查询将尽其所能...

insert into emp (empno,empname)
    select distinct empno,empname
      from ( 2 empno, 'ram' empname ) as a 
     where  a.empname not in ( select empname from emp )

如果您愿意插入多条记录,那么只需在下面找到查询

insert into emp (empno,empname)
    select max(empno),empname 
      from ( select 2 empno, 'ram' empname 
              union 
             select 3 empno, 'ram1' empname 
              union 
             select 4 empno, 'ram' empname 
           ) as a 
     where a.empname not in ( select empname from emp )
     group by empname 

【讨论】:

【参考方案2】:

INSERT 语句上不能有 WHERE 子句,WHERE 子句只能和 SELECT/UPDATE 一起使用

如果您使用 MySQL,您可以执行以下操作:

insert into emp (empno, name) values(2, 'ram') ON DUPLICATE KEY UPDATE name = 'ram'

如果你在 name 列上有一个 unique 索引,你会很安全

【讨论】:

那么,我如何在插入之前检查重复记录【参考方案3】:

如果行存在,您可以使用INSERT IGNORE 静默失败。它将尝试插入,但如果密钥存在,它将什么也不做。

INSERT IGNORE INTO emp (empno, name) VALUES (2, 'ram')

您可能还想看看INSERT ... ON DUPLICATE KEY UPDATE

【讨论】:

【参考方案4】:

你可能正在寻找类似的东西

insert into emp (empno, name) 
SELECT 2 , 'ram'
FROM emp 
WHERE 2 not in (select empno from emp) 

???

【讨论】:

为什么投反对票?这是正确的答案和 ANSI SQL,AFAIK。

以上是关于sql not in问题的主要内容,如果未能解决你的问题,请参考以下文章

sql not in问题

SQL中的NOT LIKE IN语句[重复]

Laravel Eloquent 版本的“NOT IN”SQL

为啥在 SQL 查询中 NOT IN 比 IN 慢得多

NOT IN 和 SQL 连接

SQL 中的 NOT IN 条件