2012-03-24 121 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