SQL Server 2014 在未插入的地方插入

Posted

技术标签:

【中文标题】SQL Server 2014 在未插入的地方插入【英文标题】:SQL Server 2014 Insert Where NOT IN 【发布时间】:2015-04-23 22:36:41 【问题描述】:

有 2 张桌子。第一个有fname(名字),lname(姓氏),第二个有很多列,包括:salutation(先生、博士等)、fname(名字)、mname(中间名) )、lname(姓氏)、唯一标识符和日期。

我希望从其他 2 个表中的信息中创建包含 Salutationfnamemnamelnameuidadded 的第三个表,然后我将删除第一个表并重新创建删除这些列的第二个表。

这就是我所拥有的:

CREATE TABLE MyTable
(
    Id  int  IDENTITY (1, 1) PRIMARY KEY,
    Salutation  varchar(20) NULL DEFAULT (NULL),
    Fname  varchar(30) NOT NULL,
    Mname  varchar(30) NULL DEFAULT (NULL),
    Lname  varchar(30) NOT NULL,
    Uid  uniqueidentifier NULL DEFAULT (NULL),
    Added  Date NOT NULL DEFAULT (getdate())
);

INSERT INTO MyTable (Fname, LName)
   SELECT Fname, Lname 
   FROM TABLE1

这就是我困惑的地方:

INSERT INTO MyTable (Salutation, Fname, Mname, LName, Uid, Added)
   SELECT 
      Salutation, Fname, Mname, LName, Uid, Added 
   FROM 
      Table2
   WHERE 
      Fname, Lname NOT IN (SELECT Fname, Lname FROM Table1)

有人可以更正最后的INSERT 语句以使其正常工作吗?

    它不喜欢Fname, Lname 右边的WHERE 字 我应该先从第二个表插入,然后再从第一个表插入?

【问题讨论】:

【参考方案1】:

您可以将not exists 与相关子查询一起使用:

insert into MyTable (Salutation, Fname, Mname, LName, Uid, Added)
select Salutation, Fname, Mname, LName, Uid, Added from Table2 t
where not exists (select 1 from Table1 where Fname = t.Fname and Lname = t.Lname )

更新

根据 OP 在下面 cmets 中提供的新条件,我可以确定 2 种可能的情况应该包含记录:

fnamelname 匹配; Salutationlname 匹配。

符合上述条件的查询如下:

insert into MyTable (Salutation, Fname, Mname, LName, Uid, Added)
select Salutation, Fname, Mname, LName, Uid, Added from Table2 t
where not exists (
   select 1 
   from Table1 
   where Lname = t.Lname and
       ( Fname = t.Fname or Salutation = t.Salutation )
)

【讨论】:

我发现这种方法遗漏了 1000 多条记录。我仍然在玩你的这个建议,但还没有运气。我注意到 Table2 在某些行中有一个 fname 值,但没有其他名称,所以我不想包含它。如果它有一个 fname,lname 添加它,如果它有一个称呼并且 lname 包括它,如果任何行只有一个称呼或留下其他 3 个名称字段的名称,我不希望添加该结果。有这个小文本框来回复也不是很有帮助。 @EssexMale :我已经更新了我的答案,但是我觉得这不是你想要的 100%,所以我认为你应该更详细地更新你的原始帖子和更清晰的条件确定。【参考方案2】:

left join:

INSERT INTO MyTable (Salutation, Fname, Mname, LName, Uid, Added)
SELECT t2.Salutation, t2.Fname, t2.Mname, t2.LName, t2.Uid, t2.Added FROM Table2 t2
LEFT JOIN Table1 t1 on t1.Fname = t2.Fname AND t1.Lname = t2.Lname
WHERE t1.ID IS NULL

【讨论】:

【参考方案3】:

in 语句或 not in 语句只能有一列,因此只能这样使用

INSERT INTO MyTable (Salutation, Fname, Mname, LName, Uid, Added)
SELECT Salutation, Fname, Mname, LName, Uid, Added FROM Table2
WHERE Fname NOT IN (SELECT Fname FROM Table1)'

更好的解决方案是使用 not exists 或 left join 就像其他两种用法向您展示的那样。我只是想我会解释为什么 not in 语句不起作用。

【讨论】:

嗨,米歇尔,在我问这个问题之前,我按照你的建议做了,但这对我没有好处,因为 WHERE 只占用一列,而我需要它来对抗两列,SQL 给出了一些关于仅一个可以在没有 Exists 的情况下使用。我试过 WHERE fname, lname... 和 SQL 呻吟。感谢您的建议,但不幸的是它没有帮助。我想要做的是使用你在一个插入时建议的方法,LEFT JOIN 方法,然后是一个案例来创建一个临时表,其中包含我需要删除的行,但我需要能够保存它并且到目前为止还没有解决从那里运行 DELETE

以上是关于SQL Server 2014 在未插入的地方插入的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2014 - MainTable 和 TempTable - 如果不存在则插入其他更新

SQL server2014数据库存储过程 实现游标循环读取 循环插入数据

尝试通过 ASP.NET 中的命令文本在 SQL Server 2014 中插入“Rahul's Sister”时出错 [重复]

SQL SERVER 插入加法?

在 SQL Server 中插入经过的时间

SQL Server插入空实例[重复]