SQL INSERT INTO WITH SELECT 查询

7

由于我没有SQL经验,希望有人能帮助我解决这个问题。

我有一个空的临时表,还有一张包含信息的表。

目前我的查询大纲如下:

CREATE TABLE [#Temp] (ID Int, Field1 Varchar)

INSERT INTO [#Temp]
    SELECT ID, Field1 
    FROM [Other_table] 
    WHERE ID IN (ID1, ID2, ID3...)

我正在将大量ID传递给查询,并且如果ID对应于Other_table中的ID,则必须使用此信息填充临时表。
请问是否可能在同一查询中将未匹配的ID保存到其他地方(例如另一个临时表)?或者在同一临时表中,只是在这种情况下,将Field1设置为NULL?
我需要对未匹配的ID进行额外处理,因此我需要随时访问它们。如果可以,我希望在此查询中完成所有操作,如果这是最快的方法。
编辑:
感谢大家的帮助。
抱歉,我现在看到我的问题不是很清楚。
如果Other_table包含ID 1-1000,而我传入ID 999、1000和1001,则我希望临时表包含999和1000的信息,并且还具有ID=1001的记录以及Field1=NULL。我不希望将ID 1-998返回并将Field1设置为NULL。

SELECT ID, Field1 FROM [Other_table] WHERE ID NOT IN (ID1, ID2, ID3...)? - Nitin Varpe
好的,也许我漏掉了什么,但那只会做与我的当前查询相反的事情;我想要在同一个查询中同时实现两个结果?或者以最快的方式实现这两个结果。 - Alex
3个回答

4

每个插入语句只能使用一个目标表。因此,将field1保持为空似乎是最简单的方法:

INSERT INTO [#Temp]
SELECT ID, CASE WHEN ID IN (ID1, ID2, ID3...) THEN Field1 END
FROM [Other_table] 

如果 ID 不在列表中,case 语句将返回 null

更新
在您更新了问题之后,我建议您执行以下操作: 首先,将您在 in 运算符中使用的 ID 列表插入到另一个临时表中:

create table #tempIDs (id int)
insert into #tempIDs values(id1), (id2), (id3), ....

然后只需使用简单的左连接:

INSERT INTO [#Temp]
SELECT t1.ID, Field1 
FROM #tempIDs t1 
LEFT JOIN [Other_table] t2 ON(t1.id = t2.id)

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Alex

2

您需要创建另一个查询来处理不在ID列表中的记录。

SELECT ID, Field1 
into #temp1
FROM [Other_table] WHERE ID NOT IN (ID1, ID2, ID3...)

还有另一个

SELECT ID, Field1 
into #temp2
FROM [Other_table] WHERE ID IN (ID1, ID2, ID3...)

“我需要在未匹配的ID上进行额外的工作”是什么意思?您能否添加更多细节,也许我们可以在一个查询中完成而不是分开处理。

更新

这个 (ID1, ID2, ID3...) 是从哪里来的?我们能使用联接吗?如果您的答案是“是”,那么您将得到想要的结果。

试试这个方法。

SELECT *  Into #temp 
FROM(
  SELECT ID, Field1 
  FROM [Other_table] 
  WHERE ID IN (ID1, ID2, ID3...)
  Union
  SELECT ID, Field1 
  FROM [Other_table] 
  WHERE ID NOT IN (ID1, ID2, ID3...)
)

或者这个

SELECT ID, Field1 into #temp
  FROM [Other_table] 
  WHERE ID IN (ID1, ID2, ID3...)
  Union
  SELECT ID, Field1 
  FROM [Other_table] 
  WHERE ID NOT IN (ID1, ID2, ID3...)

谢谢,你认为我必须执行两个查询,这正是我想的,但我想确认一下。 "其他工作" 意味着查询另一个服务器以获取此信息,据我所知,这部分与我的问题无关。 我希望临时表格包含找到的信息,并且未找到的 ID 列表易于使用。 - Alex
@Alex,我已更新我的答案,你可以在这种情况下使用 _Union_,并将结果存储在同一个 #temp-table 中。 - The Reason
只有一种方法可以获取这些数据,你可以添加自己的方法,我试图避免使用_case_语句,是的,你也可以用case做同样的事情。谢谢。 - The Reason
在一个有100000条记录的表上,比较我的建议和你的执行计划,结果我的方案所需时间不到联合查询的一半(32% vs 68%)。 - Zohar Peled
是的,在这种情况下最好使用“case语句”,你说得对! - The Reason
显示剩余3条评论

2

最快的解决方法是从另一个表中获取所有在你的临时表中不存在的值。我已将那些ID的Field1标记为NULL。

CREATE TABLE [#Temp] (ID Int, Field1 Varchar)

INSERT INTO [#Temp]
    SELECT ID, Field1 
    FROM [Other_table] 
    WHERE ID IN (ID1, ID2, ID3...)

INSERT INTO [#Temp]
SELECT ID, NULL AS Field1
FROM [Other_Table]
WHERE ID NOT IN (SELECT DISTINCT ID FROM #Temp)

另一种方法是在相同的INSERT语句中包含它。
CREATE TABLE [#Temp] (ID Int, Field1 Varchar(100))

INSERT INTO [#Temp]
    SELECT ID, 
        CASE WHEN ID IN (ID1,ID2....) THEN Field1
             ELSE NULL END AS 'Field1'
    FROM [Other_Table] 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接