Polecenie Wybierz, aby znaleźć duplikaty na niektórych polach

Czy możesz mi pomóc z poleceniami SQL, aby znaleźć duplikaty na wielu polach?

Na przykład w pseudo kodzie:

select count(field1,field2,field3) 
from table 
where the combination of field1, field2, field3 occurs multiple times

I z powyższej instrukcji jeśli występuje wiele wystąpień chciałbym wybrać każdy rekord z wyjątkiem pierwszego.

Author: joragupra, 2010-12-14

6 answers

Aby uzyskać listę pól, dla których istnieje wiele rekordów, możesz użyć..

select field1,field2,field3, count(*)
  from table_name
  group by field1,field2,field3
  having count(*) > 1

Sprawdź ten link, aby uzyskać więcej informacji na temat usuwania wierszy.

Http://support.microsoft.com/kb/139444

Edit: jak wspomnieli inni użytkownicy, powinno istnieć kryterium decydujące o tym, jak definiujesz "pierwsze wiersze", zanim użyjesz podejścia pod linkiem powyżej. Na tej podstawie będziesz musiał użyć klauzuli order by i podrzędnego zapytania w razie potrzeby. Jeśli możesz opublikować próbkę data, to by naprawdę pomogło.

 811
Author: Rajesh Chamarthi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-13 22:56:50

Wspominasz "pierwszy", więc zakładam, że masz jakiś porządek na swoich danych. Załóżmy, że Twoje dane są uporządkowane przez jakieś pole ID.

Ten SQL powinien ci dać duplikaty wpisów z wyjątkiem pierwszego. Zasadniczo wybiera wszystkie wiersze, dla których istnieje inny wiersz z (a) tymi samymi polami i (b) niższym identyfikatorem. Wydajność nie będzie świetna, ale może rozwiązać twój problem.

SELECT A.ID, A.field1, A.field2, A.field3
  FROM myTable A
 WHERE EXISTS (SELECT B.ID
                 FROM myTable B
                WHERE B.field1 = A.field1
                  AND B.field2 = A.field2
                  AND B.field3 = A.field3
                  AND B.ID < A.ID)
 42
Author: Heinzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-13 22:39:54

Jest to zabawne rozwiązanie z SQL Server 2005, które lubię. Zakładam, że przez "dla każdego rekordu z wyjątkiem pierwszego" masz na myśli, że istnieje inna kolumna "id", której możemy użyć do określenia, który wiersz jest"pierwszy".

SELECT id
    , field1
    , field2
    , field3
FROM
(
    SELECT id
        , field1
        , field2
        , field3
        , RANK() OVER (PARTITION BY field1, field2, field3 ORDER BY id ASC) AS [rank]
    FROM table_name
) a
WHERE [rank] > 1
 17
Author: Nick Vaccaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-13 23:03:49

Aby zobaczyć zduplikowaną wartość

with MYCTE  as (
               select row_number() over ( partition by name  order by name) rown,   * from tmptest  

                ) 
              select * from MYCTE where rown <=1
 5
Author: manoj Verma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-29 11:58:47

Jeśli używasz SQL Server 2005 lub nowszego (a tagi dla Twojego pytania wskazują SQL Server 2008), możesz użyć funkcji rankingowych, aby zwrócić zduplikowane rekordy po pierwszym, jeśli użycie łączy jest mniej pożądane lub niepraktyczne z jakiegoś powodu. Poniższy przykład pokazuje to w akcji, gdzie działa również z wartościami null w badanych kolumnach.

create table Table1 (
 Field1 int,
 Field2 int,
 Field3 int,
 Field4 int 
)

insert  Table1 
values    (1,1,1,1)
        , (1,1,1,2)
        , (1,1,1,3)
        , (2,2,2,1)
        , (3,3,3,1)
        , (3,3,3,2)
        , (null, null, 2, 1)
        , (null, null, 2, 3)

select    *
from     (select      Field1
                    , Field2
                    , Field3
                    , Field4
                    , row_number() over (partition by   Field1
                                                      , Field2
                                                      , Field3
                                         order by       Field4) as occurrence
          from      Table1) x
where     occurrence > 1

Zauważ po uruchomieniu tego przykładu, że pierwszy rekord z każdej "grupy" jest wykluczony i że rekordy z null wartości są obsługiwane prawidłowo.

Jeśli nie masz kolumny do porządkowania rekordów w grupie, możesz użyć kolumny partycji według kolejności kolumn.

 3
Author: Bradford Hoagland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-13 22:59:22
CREATE TABLE #tmp
(
    sizeId Varchar(MAX)
)

INSERT  #tmp 
    VALUES ('44'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46')


SELECT * FROM #tmp
DECLARE @SqlStr VARCHAR(MAX)

SELECT @SqlStr = STUFF((SELECT ',' + sizeId
              FROM #tmp
              ORDER BY sizeId
              FOR XML PATH('')), 1, 1, '') 


SELECT TOP 1 * FROM (
select items, count(*)AS Occurrence
  FROM dbo.Split(@SqlStr,',')
  group by items
  having count(*) > 1
  )K
  ORDER BY K.Occurrence DESC    
 1
Author: Mr.X,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-19 11:50:32