2015-12-23 6 views
5

Ho una domanda su SQL Server.Elimina dati duplicati e carica in un'altra tabella in SQL Server

Tabella: emp

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

Questa tabella ha i dati duplicati in base alla tabella sopra Voglio eliminare i dati duplicati dal emp tavolo

e duplicare i dati devono essere caricati in empduplicate tavolo.

Qui empid è unico. Se empid si presenta più volte, allora quel record è considerato un duplicato.

empduplicate struttura simile a questa:

Empid | name | sal 

Finalmente dopo l'eliminazione di dati duplicati, voglio vedere i dati in emp tabella simile a questa:

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

Per l'eliminazione dei duplicati, ho provato questo codice :

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

Ma non riesco a d elete interi record.

Esempio: empid=2 ha dati duplicati

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

Devo cancellare tutto il empid=2 record corrispondenti. empid=2 ha duplicato e deve eliminarlo dalla tabella emp.

E empduplicate tavolo bisogno di caricare i dati duplicati simile a questa:

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

Per inserire i dati duplicati ho provato questo codice:

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

Quella di query genera un errore:

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

Per favore dimmi come scrivere una query per ottenere il mio compito in SQL Server

risposta

2

Sei quasi arrivato. Invece di utilizzare ROW_NUMBER, utilizzare 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; 

è necessario eseguire il primo INSERT prima della DELETE. Inoltre, potresti voler racchiuderlo in una singola transazione.

+0

Grazie relativo funzionamento benissimo – 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.