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
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
SELECT name, city, count(*) as qty
FROM stuff
GROUP BY name, city HAVING count(*)> 1
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)
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
É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
.
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» }.
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