SQL获取项目不在列表中

时间:2013-01-23 17:20:34

标签: sql sql-server sql-server-2008 tsql

我正在使用MS SQL Server 2008 R2,我有一个电子表格的电子邮件列表,我将其插入针对用户表的查询中。在列表中的821封电子邮件中,它返回了759行。有没有简单的方法让它返回不在表中的电子邮件?我只对数据库具有读访问权限,因此无法创建包含电子邮件列表的表 - 仅获取结果。这是我用来获取那些电子邮件列表的查询的简化版本:

select *
from UserTbl
where username in ('email1','email2','email3',...'email821')

我可以提出一个Unix shell解决方案,但知道如何在MS SQL中执行它会更有用。我实际上发现了一些接近stackoverflow解决方案的东西(“T-SQL:如何选择值列表中的值不在表中?”),但它似乎对我不起作用(为了我的需要,我只想要不在表输出中的列表):

SELECT username,
    CASE
        WHEN EXISTS(SELECT * FROM UsersTbl tu WHERE E.email = tu.username) THEN 'Exist'
        ELSE 'Not Exist'
    END AS
FROM (VALUES('email1'),('email2'),('email3'),('email4')) E(email)

当我运行查询时,这给了我错误“关键字'FROM'附近的语法不正确”。顺便说一句,我正在谷歌上搜索上面使用的VALUES关键字的描述,但没有找到任何有用的信息。

如果有人能帮助我,我们将不胜感激。

谢谢, 本

4 个答案:

答案 0 :(得分:11)

如果你只想要一个尚未出现的电子邮件列表,这似乎更简单:

SELECT e.email
FROM 
(
  VALUES('email1'),('email2'),('email3'),('email4')
) AS e(email)
WHERE 
NOT EXISTS
(
  SELECT 1
    FROM dbo.UsersTbl 
    WHERE username = e.email
);

甚至更简单:

SELECT e.email 
FROM 
(
  VALUES('email1'),('email2'),('email3'),('email4')
) AS e(email)
EXCEPT
SELECT username FROM dbo.UsersTbl;

要了解为什么我更喜欢NOT EXISTS / EXCEPT而不是LEFT JOIN或其他替代方案,请参阅:

http://www.sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join

答案 1 :(得分:4)

似乎你只是在“AS”之后错过了一个别名

SELECT username,
    CASE
        WHEN EXISTS(SELECT * FROM UsersTbl tu WHERE E.email = tu.username) THEN 'Exist'
        ELSE 'Not Exist'
    END AS doesExist
FROM (VALUES('email1'),('email2'),('email3'),('email4')) E(email)

答案 2 :(得分:3)

你所拥有的非常接近,你只需要为第二列实际指定别名。此外,我认为您要选择E.email,而不是空username列(如果您要加入桌面)

SELECT E.email,
    CASE
        WHEN EXISTS(SELECT * FROM UsersTbl tu WHERE E.email = tu.username) THEN 'Exist'
        ELSE 'Not Exist'
    END AS ex
FROM (VALUES('email1'),('email2'),('email3'),('email4')) E(email)

虽然为了获取未导入的电子邮件列表,我可能只会这样做:

SELECT E.email
FROM (VALUES('email1'),('email2'),('email3'),('email4')) E(email)
LEFT OUTER JOIN UsersTbl tu ON E.email = tu.username
WHERE tu.username IS NULL

或者,

SELECT E.email
FROM (VALUES('email1'),('email2'),('email3'),('email4')) E(email)
WHERE NOT EXISTS
(
    SELECT 1
    FROM UsersTbl tu 
    WHERE E.email = tu.username
)

答案 3 :(得分:0)

完全自动化的一种方法是使用openrowset将电子表格用作数据库。但是,可能不允许使用openrowset,并且您的excel文件需要位于服务器上或可通过网络路径访问。

Here is a great tutorial I have found Spreadsheet http://www.sql-programmers.com/tsql-openrowset-in-sql-server.aspx

Declare @UserTbl Table
(
    email nVarchar(255),
    firstname nVarchar(255),
    lastname nVarchar(255)
)

INSERT into @UserTbl VALUES('user1@email.com','User','1')
INSERT into @UserTbl VALUES('user2@email.com','User','2')
INSERT into @UserTbl VALUES('user3@email.com','User','3')

select *
from @UserTbl
where email not in (SELECT Email FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0','Excel 8.0;Database=C:\email.xls;HDR=YES', 'SELECT * FROM [Feuil1$]')
)

-- Sample to read a file from Excel     SELECT * FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0','Excel 8.0;Database=C:\email.xls;HDR=YES', 'SELECT * FROM [Feuil1$]')