2013-01-04 53 views
0

你好,我正在努力得到正確的查詢。我想要的是返回具有唯一名稱和姓氏的行。我得到的是重複SQL不存在(跳過重複項)

所有行這是我的SQL

DECLARE @tmp AS TABLE (Name VARCHAR(100), Surname VARCHAR(100)) 

INSERT INTO @tmp 

SELECT CustomerName,CustomerSurname FROM Customers 
WHERE 
NOT EXISTS 
(SELECT Name,Surname 
FROM @tmp 
WHERE Name=CustomerName 
AND ID Surname=CustomerSurname 
GROUP BY Name,Surname) 

請能有人指出我朝着正確的方向。 //絕望(我試過沒有GROUP BY,但得到相同的結果)

+1

請提供'客戶'的表格定義以及示例數據和期望的結果。 –

+0

SQL進程*集合*,並且每個最外層查詢的結果都會產生,就好像所有處理並行發生一樣。因此,對於上面的腳本,在處理「INSERT」時,「@ tmp」將始終爲空。你可以試着解釋你認爲的這個查詢會做什麼嗎? –

+0

我希望能做到的是獲得一個'史蒂文史密斯'而不是客戶中的每一個史蒂文史密斯,而且每一個'史蒂文'的姓氏不是'史密斯' – Constanta

回答

3

DISTINCT會做的伎倆。

SELECT DISTINCT CustomerName, CustomerSurname 
FROM Customers 

Demo

如果你只是想真的沒有重複的(而不是表現爲一個單一的記錄獲得一式兩份)的記錄,你可以使用GROUP BYHAVING

SELECT CustomerName, CustomerSurname 
FROM Customers 
GROUP BY CustomerName, CustomerSurname 
HAVING COUNT(*) = 1 

Demo

+0

我認爲這不是他們所要求的。這將帶回所有'CustomerName,CustomerSurname'和'DISTINCT'使得唯一唯一唯一。我認爲他們只是想要那些實際上是獨一無二的。 –

+0

@MartinSmith:從發佈的代碼看來,OP試圖只插入那些還沒有存在臨時表中的項目,如果它們能夠正常工作,那麼它就相當於不同的,所以我猜這是它。 –

+0

查看您的意思! –

0

你在做@Tmp表仍然是空的時候嗎? 如果是這樣的話:您的整個「select」在「insert」語句之前完全評估,它不會「執行查詢並添加一行,插入行,運行查詢並獲取另一行,插入行等「。

如果你想只插入唯一的客戶,使用相同的「客戶」表中的不存在條款

SELECT c.CustomerName,c.CustomerSurname FROM Customers c 
WHERE 
NOT EXISTS 
(SELECT 1 
FROM Customers c1 
WHERE c.CustomerName = c1.CustomerName 
AND c.CustomerSurname = c1.CustomerSurname 
AND c.Id <> c1.Id) 

如果要插入一個獨特的客戶羣,用「不同」

+0

是的空表。好吧,我明白'爲什麼'我現在嘗試不起作用,謝謝比德 – Constanta

+0

@beder:您提供的查詢保證返回0行。除非在2列中有空值。它實際上等價於'SELECT CustomerName,CustomerSurname FROM Customers'''''客戶名稱爲NULL或CustomerSurname爲NULL;' –

+0

如果您在子查詢中添加了AND c.ID <> c1.ID',它將按照您的描述工作。 –

0

首先,我認爲@David答案就是你想要的。但重讀你的意見,也許你想名字和姓氏的所有組合:

SELECT n.CustomerName, s.CustomerSurname 
FROM 
    (SELECT DISTINCT CustomerName 
     FROM Customers 
    ) AS n 
    CROSS JOIN 
    (SELECT DISTINCT CustomerSurname 
     FROM Customers 
    ) AS s ; 
0

通常情況下,如果你正在做一個WHERE NOT EXISTS或WHERE EXISTS,或NOT IN子查詢, 你應該使用什麼叫做一個「相關的子查詢」,就像在ypercube上面的回答中一樣,其中表內部和外部表使用表別名(表內部連接到外部表)。 ypercube舉了一個很好的例子。

而且往往NOT EXISTS優於NOT IN(除非WHERE NOT IN是從一個完全無關的表,你不能參加上選擇。)

有時候,如果你很想做一個WHERE EXISTS(從列中沒有重複值的小表中選擇),您也可以通過將主查詢與EXISTS中想要的列上的該表連接起來做同樣的事情。並非總是最好或最安全的解決方案,如果該表中有許多行可能會使查詢速度變慢,並且如果連接表中的該列有dup值,可能會導致許多重複行 - 在這種情況下,您必須添加DISTINCT到主查詢,這會導致它將所有列上的數據分類。 - 效率不高。

而且,類似地,如果您將LEFT OUTER JOIN添加到您要子查詢的表中並添加WHERE,則可以完成WHERE NOT IN或NOT EXISTS相關子查詢(並提供完全相同的執行計劃)。一片空白。 你必須小心使用它,但你不需要DISTINCT。坦率地說,我更喜歡使用WHERE NOT IN子查詢或NOT EXISTS相關子查詢,因爲語法使得意圖清晰並且很難出錯。

而且你不需要在這樣的子查詢中使用DISTINCT(相關或不相關)。這會浪費處理(對於WHERE EXISTS或WHERE IN子查詢,SQL優化器無論如何都會忽略它,只是使用與外部查詢中的每一行匹配的第一個值)。 (希望有道理。)