6

我正在使用 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

4 回答 4

16

如果您只想要尚不存在的电子邮件列表,这似乎要简单得多:

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或其他替代方案,请参阅:EXCEPTLEFT JOIN

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

于 2013-01-23T18:00:33.003 回答
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)
于 2013-01-23T17:25:55.990 回答
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
)
于 2013-01-23T17:27:10.670 回答
0

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

这是我找到的电子表格 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$]')
于 2013-01-23T18:49:10.023 回答