2012-06-20 7 views
5

Mam tabelę z pewnymi zduplikowanymi wierszami. Chcę usunąć tylko jeden zduplikowany wiersz.Zapytanie sql do usunięcia tylko jednego zduplikowanego wiersza

Na przykład I'v 9 duplikatów wierszy, więc powinien usunąć tylko jeden wiersz i powinien wyświetlić 8 pozostałych wierszy.

przykład

data powołania zwany okres timestampp

2012-06-19 10:22:45.000 165 218 155 1.9 121 
2012-06-19 10:22:45.000 165 218 155 1.9 121 
2012-06-19 10:22:45.000 165 218 155 1.9 121 
2012-06-19 10:22:45.000 165 218 155 1.9 121 

z góry terminie należy usunąć tylko jeden wiersz i powinien pokazać 3 rzędy

2012-06-19 10:22:45.000 165 218 155 1.9 100 
2012-06-19 10:22:45.000 165 218 155 1.9 100 
2012-06-19 10:22:45.000 165 218 155 1.9 100 

z góry terminie należy usunąć tylko jeden wiersz i powinien pokazać 2 wiersze.

Jak mogę to zrobić?

+0

Czy możesz sformatować dane, aby były bardziej czytelne? – codingbiz

+0

Istnieje pięć nazw kolumn wymienionych, ale sześć kolumn na wyjściu. A jak zmienia się ostatnia kolumna z 121 na 100? Jeśli źródło ma dwa wiersze z 121 i dwoma wierszami ze 100, czy usuniesz dwa wiersze lub jeden? (Innymi słowy, czy duplikat jest oparty tylko na dacie?) –

Odpowiedz

1

Czy masz klucz podstawowy na stole?

Co sprawia, że ​​wiersz jest duplikatem? W tym samym czasie? ta sama data? wszystkie kolumny są takie same?

Jeśli masz klucz podstawowy można użyć funkcji TOP wybrać tylko jeden rekord i usuwać że jeden rząd:

Delete from [tablename] where id in (select top 1 id from [tablename] where [clause]) 
3

Jeśli nie przeszkadza kolejność tych wierszach jest polecenie MySQL:

DELETE TOP (numberOfRowsToDelete) FROM db.tablename WHERE {condition for ex id = 5}; 
+0

i oczywiście możesz użyć instrukcji WHERE, aby określić, która data ma zostać usunięta. – Reshi

+2

OP poprosił o rozwiązanie SQL Server. – Spikeh

1

Dla SQL Server 2005+ można wykonać następujące czynności:

;WITH CTE AS 
(
    SELECT *, 
      ROW_NUMBER() OVER(PARTITION BY [date], calling, called, duration, [timestamp] ORDER BY 1) RN 
    FROM YourTable 
) 
DELETE FROM CTE 
WHERE RN = 2 
6

rozwiązanie to pozwala usunąć jeden wiersz z każdego zestawu duplikatów (zamiast po prostu obsługi pojedynczy blok duplikatów na raz):

;WITH x AS 
(
    SELECT [date], rn = ROW_NUMBER() OVER (PARTITION BY 
    [date], calling, called, duration, [timestamp] 
    ORDER BY [date]) 
    FROM dbo.UnspecifiedTableName 
) 
DELETE x WHERE rn = 2; 

Tak na marginesie, zarówno [date] i [timestamp] są straszne wybory dla nazw kolumn ...

+0

co oznacza: Z X AS? – user2705620

+0

@ User6675636b20796f7521 Nazywa się [Common Table Expression] (http://msdn.microsoft.com/en-us/library/ms175972.aspx). –

+0

Dzięki :) to było dobre rozwiązanie. – user2705620

0

Ponieważ nie mam schematu, ja bym możliwe rozwiązanie w krokach:

  1. zastosować numer wiersza do select wszystkich kolumn
  2. Dokonaj przez grupę z tych kolumn i usuwać mI N (RowNumber) w każdej grupie

Edycja:

RowNumber znajduje się na wewnętrznej i hasła będzie miał ROWNUMBER wzrastających we wszystkich rzędach. W zapytaniu zewnętrznym tworzę grupę według zapytania wewnętrznego i wybieram min (rownumber) dla każdej grupy. Ponieważ każda grupa składa się ze zduplikowanych wierszy, usuwam min (rownumber) dla każdej grupy.

+1

MIN będzie zawsze wynosić 1 dla każdej grupy, jeśli podzielone na partycje przez te same kolumny. Oznacza to, że usuniesz także wiersze, które * nie * mają duplikatów, chyba że dodasz również HAVING. Co sprawia, że ​​jest jeszcze bardziej skomplikowana niż rozwiązania już opublikowane, IMHO. –

+0

@AaronBertrand nop, rownumber znajduje się w wewnętrznej kwerendzie i będzie rosnąć rownumber we wszystkich wierszach. W zapytaniu zewnętrznym tworzę grupę według zapytania wewnętrznego i wybieram min (rownumber) dla każdej grupy. Ponieważ każda grupa składa się ze zduplikowanych wierszy, usuwam min (rownumber) dla każdej grupy. Zrozumiałeś? –

+0

Lepszy opis, oczywiście, ale nie pasuje do Twojego pierwszego opisu. Kod byłby bardziej użyteczny i oczywisty. –

0

użyciu LIMIT 1 pomoże usunąć tylko 1 ROW, który pasuje do Twojego zapytania: DELETE

DELETE FROM `table_name` WHERE `column_name`='value' LIMIT 1; 

PRZED:

+----------------------+ 
| id | column_name | 
+-----+----------------+ 
| 1 | value   | 
+-----+----------------+ 
| 2 | value   | 
+-----+----------------+ 
| 3 | value   | 
+-----+----------------+ 
| 4 | value   | 
+-----+----------------+ 

PO:

+----------------------+ 
| id | column_name | 
+-----+----------------+ 
| 1 | value   | 
+-----+----------------+ 
| 2 | value   | 
+-----+----------------+ 
| 3 | value   | 
+-----+----------------+ 
Powiązane problemy