假设我有一个表Product
,其中包含一个名为ProductName
的列,其值为:
Lawnmower
Weedwacker
Backhoe
Gas Can
Batmobile
现在,我在记事本中列出了应该从结果集中排除的产品,即:
Lawnmower
Weedwacker
Batmobile
在我的现实问题中,有成千上万的记录和成千上万的排除。在SQL Studio Manager中,如何构造类似于以下伪代码的查询,该伪代码只返回Backhoe
和Gas Can
作为结果?:
declare @excludedProductNames varchar(MAX) =
'Lawnmower
Weedwacker
Batmobile'
SELECT ProductName FROM Product
WHERE ProductName isn't in the list of @excludedProductNames
这只是一次性报告,所以我根本不关心表现。
答案 0 :(得分:3)
首先要将这些单词放入SSMS中 - 您可以使用UNION ALL构建派生表:
SELECT 'Lawnmower' AS word
UNION ALL
SELECT 'Weedwacker'
UNION ALL
SELECT 'Batmobile'
这将返回一个包含单个列的表,名为“word”:
word
--------
Lawnmower
Weedwacker
Batmobile
您需要转义数据中的任何单引号。 IE:O'Brian需要改为O''Brian - 只需加倍单引号就可以逃脱它。
现在,真正的查询...
有些数据库限制了IN中的条款数量,在数千个IIRC的某个地方,因此NOT EXISTS
或LEFT JOIN/IS NULL
可能是更好的选择。
SELECT p.*
FROM PRODUCT p
WHERE p.productname NOT IN (SELECT 'Lawnmower' AS word
UNION ALL
SELECT 'Weedwacker'
UNION ALL
SELECT 'Batmobile'
...)
SELECT p.*
FROM PRODUCT p
WHERE NOT EXISTS (SELECT NULL
FROM (SELECT 'Lawnmower' AS word
UNION ALL
SELECT 'Weedwacker'
UNION ALL
SELECT 'Batmobile'
...) x
WHERE x.word = p.productname)
SELECT p.*
FROM PRODUCT p
LEFT JOIN (SELECT 'Lawnmower' AS word
UNION ALL
SELECT 'Weedwacker'
UNION ALL
SELECT 'Batmobile'
...) x ON x.word = p.productname
WHERE x.word IS NULL
如果比较的列不可为空,NOT IN or NOT EXIST are the best choice。
答案 1 :(得分:1)
我认为你最好使用一些文本编辑器技巧来实现这一目标。例如,使用', '
替换换行符,您可以轻松地进行select * from product where ProductName not in ('...', '...')
查询。
答案 2 :(得分:0)
创建一个临时表,在那里加载所有排除项,并选择临时表中不存在的所有行。
-- create temp table #exclusions
select ProductName into #exclusions
from Product
where 1 = 2
# run a bunch of inserts
insert into #exclusions (ProductName) values ('LawnMower')
-- as many as needed...
# run your select
select * from Product
where ProductName not in (select Product from #exclusions)
drop table #exclusions
作为运行大量插入内容的替代方法,使用bcp将包含ProductNames的csv文件上传到非临时表中。