2012-03-24 120 views
36

我正在验证具有电子商务网站的事务级别数据的表并查找确切的错误。使用SQL Server查找表中的重复记录

我希望您的帮助能够在SQL Server上的50列表中找到重复的记录。

假设我的数据是:

OrderNo shoppername amountpayed city Item  
1  Sam   10   A Iphone 
1  Sam   10   A Iphone--->>Duplication to be detected 
1  Sam   5   A Ipod 
2  John  20   B Macbook 
3  John  25   B Macbookair 
4  Jack  5   A Ipod 

假设我使用下面的查询:

Select shoppername,count(*) as cnt 
from dbo.sales 
having count(*) > 1 
group by shoppername 

将返回我

Sam 2 
John 2 

但我并不想找到刚刚复制超过1或2列。我想在我的数据中找到所有列上的重复项。我想要的结果为:

1  Sam   10   A Iphone 

回答

3

只需将所有字段添加到查询中,并记住将它们添加到Group By中。

Select shoppername, a, b, amountpayed, item, count(*) as cnt 
from dbo.sales 
group by shoppername, a, b, amountpayed, item 
having count(*) > 1 
+1

我有50场。所以没有办法,如果没有单独写出所有字段的名字,我可以找出重复的记录! – Matthew 2012-03-24 09:17:17

+5

右键单击表格,选择:脚本表格>>选择>>新建查询编辑器窗口。现在你已经有了你的SELECT列表,复制并粘贴到你的GROUP BY部分。 – JerryOL 2012-03-26 02:14:43

35
SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as cnt 
FROM dbo.sales 
GROUP BY OrderNo, shoppername, amountPayed, city, item 
HAVING COUNT(*) > 1 
56
with x as (select *,rn = row_number() 
      over(PARTITION BY OrderNo,item order by OrderNo) 
      from #temp1) 

select * from x 
where rn > 1 

您可以通过更换select语句通过

delete x where rn > 1 
+0

太好了。我在Oracle中知道这一点,但不知道这在SQL服务器中也是可能的。 – GolezTrol 2012-03-24 09:24:32

+0

优秀的答案。 – HShbib 2013-04-02 09:20:50

+1

对于任何好奇的人来说,这就是我如何在Oracle中编写它:'用x表示(选择t。*,row_number()over(PARTITION BY OrderNo,OrderNo的项目顺序)作为rn from t_dcf t)select * from x其中rn> 1;' – Juan 2015-07-01 18:56:20

1

删除重复第一试试这个

SELECT MAX(shoppername), COUNT(*) AS cnt 
FROM dbo.sales 
GROUP BY CHECKSUM(*) 
HAVING COUNT(*) > 1 

阅读有关CHECKSUM功能,可以有重复。

4
SQL> SELECT JOB,COUNT(JOB) FROM EMP GROUP BY JOB; 

JOB  COUNT(JOB) 
--------- ---------- 
ANALYST   2 
CLERK    4 
MANAGER   3 
PRESIDENT   1 
SALESMAN   4 
-2

SELECT * 从dbo.sales 组由shoppername 有(计数(项目)> 1)

+0

试试这个会有效 – Mahaveer 2015-04-17 10:58:04

+0

这将**不**工作。你会得到一个'Column在选择列表中是无效的,因为它不包含在聚合函数或GROUP BY子句中。“错误 – kkuilla 2015-04-17 11:12:58

2

要获得的多个记录列表中使用以下命令

select field1,field2,field3, count(*) 
    from table_name 
    group by field1,field2,field3 
    having count(*) > 1 
0
with x as (
select shoppername,count(shoppername) 
       from sales 
       having count(shoppername)>1 
      group by shoppername) 
select t.* from x,win_gp_pin1510 t 
where x.shoppername=t.shoppername 
order by t.shoppername 
-2

从dbo.EventInstances中选择EventID,计数()为cnt 组通过事件ID 具有计数()> 1

-2

以下是运行的代码:

SELECT abnno, COUNT(abnno) 
FROM tbl_Name 
GROUP BY abnno 
HAVING (COUNT(abnno) > 1) 
+0

请在你的答案中包含正确的格式,并解释它是如何使它更清晰的。 – 2016-10-21 05:25:22

0

首先,我怀疑结果它不准确?好像从原来的桌子上有三个'Sam'。但这个问题并不重要。

然后,我们来了这个问题本身。根据您的表格,显示重复值的最佳方式是使用count(*)Group by子句。查询应该是这样的

SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as RepeatTimes FROM dbo.sales GROUP BY OrderNo, shoppername, amountPayed, city, item HAVING COUNT(*) > 1

的原因是,从表中唯一标识每个记录,所有列在一起,这意味着该记录将被视为重复的,只有当从每列的所有值都完全相同,还想显示重复记录的所有字段,因此group by不会错过任何列,否则是,因为您只能参与'group by'子句的select列。

现在我想给你任何With...Row_Number()Over(...)的例子,它使用表格式和Row_Number函数一起使用。

假设您有一个几乎相同的表格,但有一个额外的列名为发运日期,并且即使其余值相同,值可能会更改。那就是:

OrderNo shoppername amountpayed city Item Shipping Date
1 Sam 10 A Iphone 2016-01-01 1 Sam 10 A Iphone 2016-02-02 1 Sam 5 A Ipod 2016-03-03 2 John 20 B Macbook 2016-04-04 3 John 25 B Macbookair 2016-05-05 4 Jack 5 A Ipod 2016-06-06

注意,列#2是不是如果你仍然需要所有列的单元重复一个。但是如果你想在这种情况下把它们看作是重复的呢?您应该使用With...Row_Number()Over(...),并查询应该是这样的:

WITH TABLEEXPRESSION AS (SELECT *,ROW_NUMBER() OVER (PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier) --if you consider the one with late shipping date as the duplicate FROM dbo.sales) SELECT * FROM TABLEEXPRESSION WHERE Identifier !=1 --or use '>1'

上面的查询将共同给予的结果与出货日期,例如:

OrderNo shoppername amountpayed city Item Shipping Date Identifier 1 Sam 10 A Iphone 2016-02-02 2

注意这个人是不同的从2016-01-01开始,并且2016-02-02已过滤的原因是PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier,并且装运日期不是需要处理重复记录的列之一,这意味着与2016-02-02仍然可能是一个完美的结果为您的问题。

现在总结一下吧点点,使用count(*)Group by条款在一起是最好的选择,当你只想从Group by条款作为结果显示所有列,否则你会错过那些不参加group by列。

虽然对于With...Row_Number()Over(...),它适用于所有需要查找重复记录的场景,但是,与前者相比,编写查询和设计过程稍微复杂一点。

如果您的目的是从表中删除重复记录,则必须使用后面的WITH...ROW_NUMBER()OVER(...)...DELETE FROM...WHERE之一。

希望这会有所帮助!

0

试试这个

with T1 AS 
(
SELECT LASTNAME, COUNT(1) AS 'COUNT' FROM Employees GROUP BY LastName HAVING COUNT(1) > 1 
) 
SELECT E.*,T1.[COUNT] FROM Employees E INNER JOIN T1 ON T1.LastName = E.LastName