选择不存在于另一表的数据几种写法

SQL查询优化技巧
本文探讨了三种不同的SQL查询写法,包括使用NOT IN、LEFT JOIN ON IS NULL及NOT EXISTS的方法,并对比了它们在DB2数据库中的执行效率。推荐使用NOT EXISTS写法,因为它能有效利用索引提高查询性能。

看看以下三种写法:

写法1:SELECT ... FROM A

 

WHERE A.key NOT IN (SELECT key FROM B);

 

 

 

写法2:SELECT ... FROM A

 

            LEFT JOIN B ON A.key = B.key

 

WHERE B.key is null;

 

写法3:SELECT ... FROM A

 

WHERE NOT EXISTS

 

(SELECT 'x' FROM B WHERE A.key = B.key);

 

写法1采用NOT IN的写法。很不幸DB2对于NOT IN通常采用TBSCAN(表扫描),这是效率很差的写法。最佳写法是第三种写法,如果B.key上有索引,它可以不用fetch B表的数据就可以完成查询。第二种写法采用对外表B is null判断进行过滤,效率稍差。

 

注:事实上,在DB2优化器的作用下,第二种写法与第三种写法的存取方案相关无几,只是第二种写法比第三种写法多了一步filter操作。

 

建议使用第3种写法,己使用第2种写法的代码也不必修改,因为其效率与第3种写法差不多。

 

例:

 

  SELECT A.*

 

  from EDS.TW_BCUST_200409 A LEFT OUTER JOIN KF2.TW_BCUST B ON

 

          A.TM_INTRVL_CD =B.TM_INTRVL_CD and A.CUST_ID =B.CUST_ID and

 

          A.USR_ID =B.USR_ID and A.BCUST_EFF_MO =B.BCUST_EFF_MO

 

  WHERE B.TM_INTRVL_CD is null

 

 

 

  SELECT *

 

  from EDS.TW_BCUST_200409 A

 

  where NOT EXISTS

 

     (select 'x'

 

     from KF2.TW_BCUST B

 

     WHERE A.TM_INTRVL_CD =B.TM_INTRVL_CD and A.CUST_ID =B.CUST_ID

 

             and A.USR_ID =B.USR_ID and A.BCUST_EFF_MO =

 

             B.BCUST_EFF_MO)

 

这两种写法对应的存取方案:

 

                                 

 

             RETURN                            RETURN     

 

             (   1)                            (   1)     

 

               |                                 |        

 

              BTQ                               BTQ       

 

             (   2)                            (   2)     

 

               |                                 |        

 

             FILTER                            HSJOIN     

 

             (   3)                            (   3)     

 

               |                              /      \    

 

             HSJOIN                     TBSCAN       TBSCAN

 

             (   4)                     (   4)       (   5)

 

            /      \                      |            |  

 

      TBSCAN       TBSCAN          Table:           Table:

 

      (   5)       (   6)          EDS              KF2   

 

        |            |             TW_BCUST_200409  TW_BCUST

 

 Table:           Table:         

 

 EDS              KF2            

 TW_BCUST_200409  TW_BCUST   

数据库操作中,根据的条件更新的字段是种常见的需求。可以通过 `UPDATE` 语句结合 `JOIN` 来实现这功能。以下是几种常见写法,适用于同的数据库管理系统,如 SQL Server 和 MySQL。 ### 使用 `INNER JOIN` 更新字段 如果需要根据两个之间的关联字段更新数据,可以使用 `INNER JOIN`。以下是个示例,假设存在两个 `table1` 和 `table2`,并且它们通过 `common_column` 字段关联: ```sql UPDATE table2 SET table2.column1 = table1.column1, table2.column2 = table1.column2 FROM table2 INNER JOIN table1 ON table1.common_column = table2.common_column; ``` 这条语句将 `table1` 中的 `column1` 和 `column2` 更新到 `table2` 中对应的记录上,匹配的依据是 `common_column` 字段值相等[^1]。 ### 使用 `LEFT JOIN` 更新字段 如果需要保留目标中所有记录,即使在源中没有匹配的记录,可以使用 `LEFT JOIN`。以下是个示例,假设需要更新 `people` 中的 `city_name` 字段: ```sql UPDATE people LEFT JOIN city ON people.city_code = city.code SET people.city_name = city.name; ``` 这条语句将 `city` 中的 `name` 字段更新到 `people` 中的 `city_name` 字段上,匹配的依据是 `people` 中的 `city_code` 和 `city` 中的 `code` 字段值相等[^4]。 ### 使用多更新语法 在 MySQL 中,还可以使用多更新语法来更新多个中的字段。以下是个示例,假设需要更新 `T_U_TEMPLATE` 中的 `CREATE_BY` 字段: ```sql UPDATE T_U_TEMPLATE a, TEMPLATE_TEMP_CREATE b SET a.CREATE_BY = b.OPERATER_NAME WHERE a.TEMPLATE_CODE = b.OBJECT_ID; ``` 这条语句将 `TEMPLATE_TEMP_CREATE` 中的 `OPERATER_NAME` 字段更新到 `T_U_TEMPLATE` 中的 `CREATE_BY` 字段上,匹配的依据是 `TEMPLATE_CODE` 和 `OBJECT_ID` 字段值相等[^3]。 ### 使用 `IF` 函数进行条件更新 如果需要根据条件更新字段,可以使用 `IF` 函数。以下是个示例,假设需要创建个新的 `Table3` 来替代 `Table1`: ```sql CREATE TABLE Table3 SELECT Name, TypeID, IF(TypeName IS NULL, Table2.TypeName, Table1.TypeName) AS TypeName FROM Table1 JOIN Table2 ON Table1.Name = Table2.Name; ``` 这条语句创建了个新的 `Table3`,其中的 `TypeName` 字段根据 `Table1` 和 `Table2` 的 `Name` 字段进行匹配,并根据 `TypeName` 是否为空进行条件选择[^2]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值