2013-01-23 157 views
1

我正在使用MS SQL Server 2008 R2,并且我有一个电子表格插入到用户表的查询中的电子邮件列表。在列表中的821封电子邮件中,它返回了759行。有没有简单的方法让它返回不在表格中的邮件?我只有对数据库的读取权限,因此无法使用电子邮件列表创建表格 - 只会得到结果。下面是我用来获取在那里这些邮件列表中查询的简化版本:SQL获取项目不在列表中

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

我能想出一个Unix外壳的解决方案,但它会更加有用知道该怎么办它在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) 

这给了我,当我运行查询错误“‘从’关键字附近有语法错误”。另外,我在Google上搜索上面使用的VALUES关键字的描述,并没有发现任何有用的信息。

如果任何人都可以帮助我,这将不胜感激。

感谢, 本

回答

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) 
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 
) 
+0

在这两个版本我得到的错误“消息156,15级,状态1,第6行 附近的关键字 '价值' 不正确的语法。“VALUES是否允许将列表视为一个表格? –

+0

http://www.sqlfiddle.com/#!3/4c4a1/1 –

+2

@BanAtman你的问题被标记为SQL Server 2008.你确定你是?SQL Server 2008的(或更好) –

8

如果你只是想电子邮件是不存在的名单,这似乎简单得多:

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

+0

+1,'EXCEPT'非常可读,好文章 –

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('[email protected]','User','1') 
INSERT into @UserTbl VALUES('[email protected]','User','2') 
INSERT into @UserTbl VALUES('[email protected]','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$]') 
+0

我试过这个,但没有虽然通过编写一个快速的Unix例程来输出所有的INSERT到@UserTbl ...行(其中822个)并将其粘贴到MS SQL Server中: 'Declare @UserTbl表(email nVarchar(255)); INSERT入@UserTbl VALUES('.......... etc. select * from @UserTbl where email not in(从TblUser中选择用户名) ' 它工作。如果TblUser也有一个名为email的字段,我将如何访问@TblUser中的一个,因为@ TblUser.email不起作用? –

+0

如果你有一个共同的电子邮件字段,你可以做的是'select @ from @UserTbl ut join @TblUser tu on tu.email = ut.email and tu.username is null' – HucKQC