web-dev-qa-db-fra.com

Comment trouver des doublons sur plusieurs colonnes?

Donc, je veux faire quelque chose comme ce code SQL ci-dessous:

select s.id, s.name,s.city 
from stuff s
group by s.name having count(where city and name are identical) > 1

Pour produire ce qui suit (mais ignorer où seul le nom ou la seule ville correspond, il doit figurer sur les deux colonnes):

id      name  city   
904834  jim   London  
904835  jim   London  
90145   Fred  Paris   
90132   Fred  Paris
90133   Fred  Paris
78
NimChimpsky

Dupliqué id pour les paires name et city:

select s.id, t.* 
from [stuff] s
join (
    select name, city, count(*) as qty
    from [stuff]
    group by name, city
    having count(*) > 1
) t on s.name = t.name and s.city = t.city
108
Michał Powaga
 SELECT name, city, count(*) as qty 
 FROM stuff 
 GROUP BY name, city HAVING count(*)> 1
29
Sunnny

Quelque chose comme ça fera l'affaire. Je ne connais pas les performances, alors faites quelques tests.

select
  id, name, city
from
  [stuff] s
where
1 < (select count(*) from [stuff] i where i.city = s.city and i.name = s.name)
7
ssarabando

Vous devez vous inscrire vous-même et faire correspondre le nom et la ville. Puis groupe par nombre.

select 
   s.id, s.name, s.city 
from stuff s join stuff p ON (
   s.name = p.city OR s.city = p.name
)
group by s.name having count(s.name) > 1
2
Anja

Étant donné une table intermédiaire avec 70 colonnes et 4 seulement représentant des doublons, Ce code renverra les colonnes incriminées:

SELECT 
    COUNT(*)
    ,LTRIM(RTRIM(S.TransactionDate)) 
    ,LTRIM(RTRIM(S.TransactionTime))
    ,LTRIM(RTRIM(S.TransactionTicketNumber)) 
    ,LTRIM(RTRIM(GrossCost)) 
FROM Staging.dbo.Stage S
GROUP BY 
    LTRIM(RTRIM(S.TransactionDate)) 
    ,LTRIM(RTRIM(S.TransactionTime))
    ,LTRIM(RTRIM(S.TransactionTicketNumber)) 
    ,LTRIM(RTRIM(GrossCost)) 
HAVING COUNT(*) > 1

.

0
Don G.

Utiliser count(*) over(partition by...) fournit un moyen simple et efficace de localiser les répétitions non désirées, tout en répertoriant toutes les lignes affectées et toutes les colonnes utiles:

SELECT
    t.*
FROM (
    SELECT
        s.*
      , COUNT(*) OVER (PARTITION BY s.name, s.city) AS qty
    FROM stuff s
    ) t
WHERE t.qty > 1
ORDER BY t.name, t.city

Alors que les versions les plus récentes des SGBDR prennent en charge count(*) over(partition by...)MySQL V 8.0 a introduit les "fonctions de fenêtre", comme indiqué ci-dessous (dans MySQL 8.0)

CREATE TABLE stuff(
   id   INTEGER  NOT NULL
  ,name VARCHAR(60) NOT NULL
  ,city VARCHAR(60) NOT NULL
);
INSERT INTO stuff(id,name,city) VALUES 
  (904834,'jim','London')
, (904835,'jim','London')
, (90145,'Fred','Paris')
, (90132,'Fred','Paris')
, (90133,'Fred','Paris')

, (923457,'Barney','New York') # not expected in result
;
SELECT
    t.*
FROM (
    SELECT
        s.*
      , COUNT(*) OVER (PARTITION BY s.name, s.city) AS qty
    FROM stuff s
    ) t
WHERE t.qty > 1
ORDER BY t.name, t.city
 id | nom | ville | qté 
-----: | : --- | : ----- | -: 
 90145 | Fred | Paris | 3 
 90132 | Fred | Paris | 3 
 90133 | Fred | Paris | 3 
 904834 | jim | Londres | 2 
 904835 | jim | Londres | 2 

db <> violon ici

Fonctions de la fenêtre. MySQL supporte maintenant les fonctions de fenêtre qui, pour chaque ligne d'une requête, effectuent un calcul en utilisant des lignes liées à cette rangée. Celles-ci incluent des fonctions telles que RANK (), LAG () et NTILE () . De plus, plusieurs fonctions d'agrégat existantes peuvent maintenant être utilisées en tant que fonctions de la fenêtre; par exemple, SUM () et AVG (). Pour plus d'informations, voir Section 12.21, «Fonctions de fenêtre» }.

0
Used_By_Already

Un peu tard pour le jeu sur ce post, mais j'ai trouvé cette façon d'être assez flexible/efficace

select 
    s1.id
    ,s1.name
    ,s1.city 
from 
    stuff s1
    ,stuff s2
Where
    s1.id <> s2.id
    and s1.name = s2.name
    and s1.city = s2.city
0
MattD