Dubliuojančių reikšmių paieška SQL lentelėje

Dublikatus lengva rasti naudojant vieną lauką:

SELECT name, COUNT(email) 
FROM users
GROUP BY email
HAVING COUNT(email) > 1

Taigi, jei turime lentelę

ID   NAME   EMAIL
1    John   asd@asd.com
2    Sam    asd@asd.com
3    Tom    asd@asd.com
4    Bob    bob@asd.com
5    Tom    asd@asd.com

Pagal šią užklausą gausime John, Sam, Tom, Tom, Tom, nes jie visi turi tą patį email.

Tačiau aš noriu gauti dublikatus, turinčius tą patį email ir vardą.

T. y. noriu gauti "Tom", "Tom".

Man to reikia dėl šios priežasties: Padariau klaidą ir leidau įterpti pasikartojančias vardo ir pašto reikšmes. Dabar man reikia pašalinti arba pakeisti pasikartojančias reikšmes, todėl pirmiausia turiu jas surasti.

Sprendimas
SELECT
    name, email, COUNT(*)
FROM
    users
GROUP BY
    name, email
HAVING 
    COUNT(*) > 1

Tiesiog sugrupuokite abu stulpelius.

Pastaba: pagal senesnį ANSI standartą GROUP BY turi būti visi nesugrupuoti stulpeliai, tačiau tai pasikeitė dėl "funkcinės priklausomybės" idėjos:

Reliacinių duomenų bazių teorijoje funkcinė priklausomybė - tai apribojimas tarp dviejų atributų rinkinių duomenų bazės santykyje. Kitaip tariant, funkcinė priklausomybė yra apribojimas, apibūdinantis ryšį tarp santykio atributų.

Palaikymas nėra nuoseklus:

Komentarai (10)

pabandykite tai:

declare @YourTable table (id int, name varchar(10), email varchar(50))

INSERT @YourTable VALUES (1,'John','John-email')
INSERT @YourTable VALUES (2,'John','John-email')
INSERT @YourTable VALUES (3,'fred','John-email')
INSERT @YourTable VALUES (4,'fred','fred-email')
INSERT @YourTable VALUES (5,'sam','sam-email')
INSERT @YourTable VALUES (6,'sam','sam-email')

SELECT
    name,email, COUNT(*) AS CountOf
    FROM @YourTable
    GROUP BY name,email
    HAVING COUNT(*)>1

IŠĖJIMAS:

name       email       CountOf
---------- ----------- -----------
John       John-email  2
sam        sam-email   2

(2 row(s) affected)

jei norite gauti dublikatų ID, naudokite šį:

SELECT
    y.id,y.name,y.email
    FROM @YourTable y
        INNER JOIN (SELECT
                        name,email, COUNT(*) AS CountOf
                        FROM @YourTable
                        GROUP BY name,email
                        HAVING COUNT(*)>1
                    ) dt ON y.name=dt.name AND y.email=dt.email

IŠVADOS:

id          name       email
----------- ---------- ------------
1           John       John-email
2           John       John-email
5           sam        sam-email
6           sam        sam-email

(4 row(s) affected)

norėdami ištrinti dublikatus, pabandykite:

DELETE d
    FROM @YourTable d
        INNER JOIN (SELECT
                        y.id,y.name,y.email,ROW_NUMBER() OVER(PARTITION BY y.name,y.email ORDER BY y.name,y.email,y.id) AS RowRank
                        FROM @YourTable y
                            INNER JOIN (SELECT
                                            name,email, COUNT(*) AS CountOf
                                            FROM @YourTable
                                            GROUP BY name,email
                                            HAVING COUNT(*)>1
                                        ) dt ON y.name=dt.name AND y.email=dt.email
                   ) dt2 ON d.id=dt2.id
        WHERE dt2.RowRank!=1
SELECT * FROM @YourTable

IŠVADOS:

id          name       email
----------- ---------- --------------
1           John       John-email
3           fred       John-email
4           fred       fred-email
5           sam        sam-email

(4 row(s) affected)
Komentarai (0)

Išbandykite tai:

SELECT name, email
FROM users
GROUP BY name, email
HAVING ( COUNT(*) > 1 )
Komentarai (0)