Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak usunąć zduplikowane wiersze w SQL Server 2008?

Najprostszym sposobem jest CTE (wspólne wyrażenie tabelowe). Używam tej metody, gdy mam surowe dane do zaimportowania; pierwszą rzeczą, którą robię, aby go oczyścić, jest upewnienie się, że nie ma duplikatów — że mam jakiś unikalny uchwyt do każdego wiersza.

Podsumowanie:

WITH numbered AS (
    SELECT ROW_NUMBER() OVER(PARTITION BY [dupe-column-list] ORDER BY [dupe-column-list]) AS _dupe_num FROM [table-name] WHERE 1=1
)
DELETE FROM numbered WHERE _dupe_num > 1;

Część „dupe-column-list” to miejsce, w którym wymieniasz wszystkie zaangażowane kolumny, w których chcesz, aby wartości były unikatowe. ORDER BY to miejsce, w którym decydujesz, w zestawie duplikatów, który wiersz „wygrywa”, a który zostanie usunięty. ("WHERE 1=1" to tylko osobisty nawyk).

Powodem, dla którego to działa, jest to, że SQL Server przechowuje wewnętrzne, unikalne odniesienie do każdego wiersza źródłowego wybranego w CTE. Więc kiedy DELETE jest wykonywane, wie dokładnie, który wiersz ma zostać usunięty, niezależnie od tego, co umieścisz na liście wyboru CTE. (Jeśli jesteś zdenerwowany, możesz zmienić „USUŃ” na „WYBIERZ *”, ale ponieważ masz zduplikowane wiersze, to nie pomoże; gdybyś mógł jednoznacznie zidentyfikować każdy wiersz, nie czytałbyś tego .)

Przykład:

CREATE TABLE ##_dupes (col1 int, col2 int, col3 varchar(50));
INSERT INTO ##_dupes 
    VALUES (1, 1, 'one,one')
        , (2, 2, 'two,two')
        , (3, 3, 'three,three')
        , (1, 1, 'one,one')
        , (1, 2, 'one,two')
        , (3, 3, 'three,three')
        , (1, 1, 'one,one')
        , (1, 2, '1,2');

Spośród 8 wierszy masz 5 związanych z powtarzającymi się problemami; Należy usunąć 3 rzędy. Możesz zobaczyć problemy z tym:

SELECT col1
    , col2
    , col3
    , COUNT(1) AS _total 
    FROM ##_dupes 
    WHERE 1=1 
    GROUP BY col1, col2, col3
    HAVING COUNT(1) > 1
    ORDER BY _total DESC;

Teraz uruchom następujące zapytanie, aby usunąć duplikaty, pozostawiając 1 wiersz z każdego zestawu duplikatów.

WITH numbered AS (
    SELECT ROW_NUMBER() OVER(PARTITION BY col1, col2, col3 ORDER BY col1, col2, col3) AS _dupe_num FROM ##_dupes WHERE 1=1
)
DELETE FROM numbered WHERE _dupe_num > 1;

Masz teraz 5 wierszy, z których żaden nie jest zduplikowany.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sprawdź, czy ciąg zawiera podciąg w SQL Server 2005, korzystając z procedury składowanej

  2. Tworzenie nagłówka kolumny Gridview poprzez wczytanie danych z bazy danych

  3. Jak połączyć się z bazą danych SQL z C#?

  4. Podzapytanie zwróciło więcej niż 1 wartość

  5. Uzyskaj godziny i minuty (GG:MM) od daty