2015-12-23 6 views
5

Mam pytanie dotyczące SQL Server.Usuwanie duplikatów danych i ładowanie do innej tabeli w SQL Server

Tabela: emp

empid | name |sal 
1  | abc |100 
2  | def |200 
3  | test |300 
2  | har |500 
3  | jai |600 
4  | kali |240 

Ta tabela zawiera zduplikowane dane na podstawie powyższej tabeli Chcę usunąć zduplikowane dane z tabeli

emp i powielać dane powinny być ładowane do empduplicate tabeli.

Tutaj empid jest wyjątkowy. Jeśli empid pojawia się wiele razy, to ten rekord jest uważany za duplikat.

empduplicate struktura wygląda następująco:

Empid | name | sal 

Wreszcie po usunięciu duplikatów danych, chcę zobaczyć dane emp tabeli wyglądać następująco:

empid | name | sal 
1  | abc | 100 
4  | kali | 240 

Do usuwania duplikatów, próbowałem ten kod :

;with duplicate as 
(
    select 
     *, 
     row_number()over (partition by empid order by empid) as rn 
    from emp 
) 
delete from duplicate 
where rn > 1 

Ale nie jestem w stanie usuń całe rekordy.

Przykład: empid=2 ma duplikatów danych

empid|name |sal 
2 |def |200 
2 |har |500 

muszę usunąć cały empid=2 odpowiednie zapisy. empid=2 ma duplikat i trzeba go usunąć z tabeli emp.

I empduplicate stół trzeba ładować zduplikowane dane wyglądać następująco:

empid | name |sal 
2  |def  |200 
2  |har  |500 
3  |test |300 
3  |jai  |600 

wkładania zduplikowane dane Próbowałem ten kod:

insert into empduplicate 
    select 
     id, name, sal 
    from 
     emp 
    group by 
     id 
    having 
     count(*) > 1 

To zapytanie zgłasza błąd:

Column 'duplicate.name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Proszę mi powiedzieć, jak napisać zapytanie, aby osiągnąć moje zadanie w SQL Server

Odpowiedz

2

Już prawie jesteś. Zamiast używać ROW_NUMBER użyć COUNT:

WITH CteInsert AS(
    SELECT *, 
     cnt = COUNT(empid) OVER(PARTITION BY empid) 
    FROM emp 
) 
INSERT INTO empduplicate(empid, name, sal) 
SELECT 
    empid, name, sal 
FROM CteInsert 
WHERE cnt > 1; 

WITH CteDelete AS(
    SELECT *, 
     cnt = COUNT(empid) OVER(PARTITION BY empid) 
    FROM emp 
) 
DELETE FROM CteDelete WHERE cnt > 1; 

Trzeba wykonać INSERT pierwszy przed DELETE. Dodatkowo możesz zamknąć to w pojedynczej transakcji.

+0

Dzięki jego pracy grzywny – ravi

0
BEGIN TRAN 
SELECT * INTO empduplicate FROM 
(
SELECT * 
FROM emp 
WHERE empid IN (
    SELECT empid FROM emp 
    GROUP BY empid 
    HAVING COUNT(empid)>1 
) 
) as M 

DELETE FROM emp WHERE empid IN (
SELECT empid FROM emp 
GROUP BY empid 
HAVING COUNT(empid)>1 
) 

COMMIT TRAN 
0
SELECT DISTINCT * INTO #tmp FROM emp 
DELETE FROM emp 
INSERT INTO emp 
SELECT * FROM #tmp DROP table #tmp 

SELECT * FROM emp ---------------------------- All Distinct ID 

SELECT * INTO #tmp FROM emp 
WHERE empid in(
    SELECT empid FROM emp 
    group by empid having count(*) = 1 
) 
DELETE FROM emp 
INSERT INTO emp 
SELECT * FROM #tmp DROP table #tmp 

SELECT * FROM emp ----------------------------All ID which is not duplicate 

INSERT INTO empduplicate 
    SELECT * FROM emp where empid in(
    SELECT empid FROM emp 
    group by empid having count(*) >1 
) 

SELECT * FROM empduplicate -------------------ALL Duplicate value. 
Powiązane problemy