zoukankan      html  css  js  c++  java
  • sql优化 in 和 not in 语句

    WHY?

    IN 和 NOT IN 是比较常用的关键字,为什么要尽量避免呢?

    1、效率低 

    可以参看我之前遇到的一个例子([小问题笔记(九)] SQL语句Not IN 效率低,用 NOT EXISTS试试

    2、容易出现问题,或查询结果有误 (不能更严重的缺点)

    以 IN 为例。建两个表:test1 和 test2

    create table test1 (id1 int)
    create table test2 (id2 int)
    
    insert into test1 (id1) values (1),(2),(3)
    insert into test2 (id2) values (1),(2)

    我想要查询,在test2中存在的  test1中的id 。使用IN的一般写法是:

    select id1 from test1 
    where id1 in (select id2 from test2)

    结果是:  OK 木有问题!

    但是如果我一时手滑,写成了:

    select id1 from test1 
    where id1 in (select id1 from test2)

    不小心把id2写成id1了 ,会怎么样呢?

    结果是: EXCUSE ME! 为什么不报错? 

    单独查询 select id1 from test2 是一定会报错: 消息 207,级别 16,状态 1,第 11 行 列名 'id1' 无效。

    然而使用了IN的子查询就是这么敷衍,直接查出 1 2 3

    这仅仅是容易出错的情况,自己不写错还没啥事儿,下面来看一下 NOT IN 直接查出错误结果的情况:

    给test2插入一个空值:

    insert into test2 (id2) values (NULL)

    我想要查询,在test2中不存在的  test1中的id 。

    select id1 from test1 
    where id1 not in (select id2 from test2)

    结果是: 空白! 显然这个结果不是我们想要的。我们想要3。为什么会这样呢?

    原因是:NULL不等于任何非空的值啊!如果id2只有1和2, 那么3<>1 且 3<>2 所以3输出了,但是 id2包含空值,那么 3也不等于NULL 所以它不会输出。

    (跑题一句:建表的时候最好不要允许含空值,否则问题多多。)

    HOW?

    1、用 EXISTS 或 NOT EXISTS 代替

    select *  from test1 
       where EXISTS (select * from test2  where id2 = id1 )
    
    select *  FROM test1  
     where NOT EXISTS (select * from test2  where id2 = id1 )

    2、用JOIN 代替

     select id1 from test1 
       INNER JOIN test2 ON id2 = id1 
       
     select id1 from test1 
       LEFT JOIN test2 ON id2 = id1 
       where id2 IS NULL

    妥妥的没有问题了!

    PS:那我们死活都不能用 IN 和 NOT IN 了么?并没有,一位大神曾经说过,如果是确定且有限的集合时,可以使用。如 IN (0,1,2)。

    转发自:http://www.cnblogs.com/hydor/p/5391556.html

  • 相关阅读:
    Codeforces Beta Round #92 (Div. 2 Only) B. Permutations 模拟
    POJ 3281 Dining 最大流 Dinic算法
    POJ 2441 Arrange the BUlls 状压DP
    URAL 1152 Faise Mirrors 状压DP 简单题
    URAL 1039 Anniversary Party 树形DP 水题
    URAL 1018 Binary Apple Tree 树形DP 好题 经典
    pytorch中的forward前向传播机制
    .data()与.detach()的区别
    Argparse模块
    pytorch代码调试工具
  • 原文地址:https://www.cnblogs.com/mylive/p/14281859.html
Copyright © 2011-2022 走看看