2013-01-23 168 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