SQL WHERE NOT EXISTS(跳过重复)

时间:2013-01-04 11:30:20

标签: sql-server

您好我正在努力获得下面的查询。我想要的是返回具有唯一名称和姓氏的行。我得到的是所有带有重复的行

这是我的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但得到相同的结果)

4 个答案:

答案 0 :(得分:3)

DISTINCT可以解决问题。

SELECT DISTINCT CustomerName, CustomerSurname
FROM Customers

Demo

如果您只想要真正没有重复的记录(而不是将重复项表示为单个记录),您可以使用GROUP BYHAVING

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

Demo

答案 1 :(得分:0)

你在@Tmp表还是空的时候这样做了吗? 如果是这样:你的整个“select”在“insert”语句之前被完全评估,它不会“运行查询并添加一行,插入行,运行查询并获取另一行,插入行等。 “

如果您只想插入唯一的客户,请在not exists子句中使用相同的“Customer”表

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)

如果要插入一组唯一的客户,请使用“distinct”

答案 2 :(得分:0)

首先,我认为@David的回答是你想要的。但重读你的评论,也许你想要名字和姓氏的所有组合:

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

答案 3 :(得分:0)

通常,如果您正在执行WHERE NOT EXISTS或WHERE EXISTS,或者不在子查询中, 您应该使用所谓的&#34;相关子查询&#34;,如上面的ypercube上面的答案,其中表别名用于内部和外部表(其中内部表连接到外部表)。 ypercube就是一个很好的例子。

通常,NOT EXISTS比NOT IN更受欢迎(除非WHERE NOT IN从一个完全不相关的表中选择你无法加入。)

有时如果你想要做一个WHERE EXISTS(从列中没有重复值的小表中选择),你也可以通过将主查询与你想要的列上的那个表连接来做同样的事情。在EXISTS中。并不总是最好或最安全的解决方案,如果该表中有很多行,可能会使查询速度变慢,如果连接表中该列有重复值,则可能导致许多重复行 - 在这种情况下,您必须将DISTINCT添加到主查询,这会导致它对所有列上的数据进行SORT。 - 完全没有效率。

并且,类似地,如果你LEFT OUTER JOIN你要去子查询的表 - 并且添加一个WHERE,那么可以完成WHERE NOT IN或NOT EXISTS相关子查询(并给出完全相同的执行计划)。一片空白。 你必须小心使用它,但你不需要一个DISTINCT。坦率地说,我更喜欢使用WHERE NOT IN子查询或NOT EXISTS相关子查询,因为语法使意图清晰,并且很难出错。

并且在这些子查询中不需要SELECT中的DISTINCT(相关或不相关)。这将浪费处理(对于WHERE EXISTS或WHERE IN子查询,SQL优化器无论如何都会忽略它,只使用匹配外部查询中每一行的第一个值)。 (希望这很有意义。)