前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何编写不存在即插入的 SQL

如何编写不存在即插入的 SQL

作者头像
白日梦想家
发布2020-07-20 10:04:13
1.6K0
发布2020-07-20 10:04:13
举报
文章被收录于专栏:SQL实现SQL实现

MySQL 已提供了 INSERT IGNORE INTOREPLACE INTOINSERT … ON DUPLICATE KEY UPDATE 等表达式实现不重复插入的功能,不过,要使用这些表达式,表上必须有主键或者唯一索引字段,主键或者唯一索引作为判断重复记录的依据。

如果我们想根据非主键或非唯一索引的字段做重复插入判断:不存在就插入新记录,存在则忽略。如果不用事务,这个需求有没有办法实现呢?

有的!

下面就为大伙端上这道菜,请慢用。

我们需要明确的是:单纯使用 INSERT INTO 表 VALUES() 语句是没法实现这个功能的,需要使用复合语句 INSERT INTO 表 SELECT 目标值 FROM ... 才能搞定。

判断一个表里面的某个字段是否存在特定的值,可以使用 not exists 或者 not in 表达式。

代码语言:javascript
复制
# not exists 表达式
not exists(select null from 目标表 
where 目标字段 = 目标值)

# not in 表达式
目标字段 not in (目标值)

那怎么把输入的数据看作是从表里面查出来,并能用到上面的过滤条件呢?

MySQL 支持一些不需要查表的 SQL 语句,比如 SELECT 1SELECT NOW() 语句。因此我们可以把输入的数据当成 select 子句的字段。当需要用到 where 子句时就必须得有一个表,我们生成只有一条记录的衍生表。

解决方案已经呼之欲出,上面的 SQL 片段拼接起来的伪 SQL 看起来是这样。

代码语言:javascript
复制
insert into 目标表
select 包含目标值的输入数据
from (select 1) as t
where not exists(
    select null from 目标表 
    where 目标字段 = 目标值
)

假设要操作的表叫作 lucky,它有一个字段 address,当有新的地址出现的时候就往 lucky 表插入数据。现在 lucky 是一张空表,里面什么数据也没有。

代码语言:javascript
复制
CREATE TABLE `lucky` (
  `address` varchar(64) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

执行下面的 SQL,将会往 lucky 表里插入一个地址为 abc 的记录。

代码语言:javascript
复制
INSERT INTO lucky (address) 
SELECT 
  'abc' 
FROM
  (SELECT 
    1) t 
WHERE NOT EXISTS 
  (SELECT 
    NULL 
  FROM
    lucky 
  WHERE address = 'abc')

再次执行同样的 SQL,lucky 表没有新增记录,说明该 SQL 已实现了避免插入重复数据的功能。

上面的 SQL 也可以改成左连接的形式:

代码语言:javascript
复制
INSERT INTO lucky (address) 
SELECT 
  'abc' 
FROM
  (SELECT 1) t 
  LEFT JOIN lucky 
    ON address = 'abc' 
WHERE address IS NULL 
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SQL实现 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档