Méthode optimale de détermination du nombre d'inputs de table qui sont dupliquées sur des colonnes particulières

J'ai besoin de déterminer si des lignes de table particulières sont uniques sur des colonnes particulières. Actuellement, je le fais en utilisant une sous-requête comme ceci:

SELECT t1.ID, (SELECT COUNT(*) FROM MyTable AS t2 WHERE (t2.FirstName = t1.FirstName) AND (t2.Surname = t1.Surname) ) AS cnt FROM MyTable AS t1 WHERE t1.ID IN (100, 101, 102); 

Ce qui fonctionne bien. Cependant, j'aimerais savoir si quelqu'un connaît un moyen plus efficace d'get le même résultat que d'utiliser une sous-requête.

Je le fais sur un server SQL Azure, d'ailleurs.

Vous pourriez utiliser un groupe comme ceci:

 SELECT t1.FirstName, t1.Surname, COUNT(t1.ID) as cnt FROM MyTable AS t1 WHERE t1.ID IN (100, 101, 102) GROUP BY t1.FirstName, t1.Surname ORDER BY cnt DESC 

Vous pouvez append un HAVING cnt> 1 après la clause GROUP BY si vous souhaitez filterr uniquement les duplicates.

Cependant, cela dépend si vous avez besoin de la colonne ID, si vous le faites, vous devrez peut-être utiliser une sous-requête.

Ici vous pouvez find plus d'informations sur le sujet: http://technet.microsoft.com/en-us/library/ms177673.aspx

Je ne sais pas comment cela va se comparer à votre requête dans votre environnement, mais je m'attends à ce que cela fonctionne mieux:

 Select id, qty From mytable Inner join ( Select firstname, surname, count(0) as qty From mytable Group by firstname, surname ) as qtytable On mytable.firstname = qtytable.firstname and mytable.surname = qtytable.surname 

Je pense qu'un moyen plus efficace serait d'utiliser la fonction COUNT avec la clause OVER ou la fonction de classment ROW_NUMBER

 SELECT ID, COUNT(*) OVER(PARTITION BY FirstName, Surname) AS cnt FROM MyTable WHERE ID IN (100, 101, 102) 

OU

 SELECT ID, ROW_NUMBER() OVER(PARTITION BY FirstName, Surname ORDER BY ID) AS rn FROM MyTable WHERE ID IN (100, 101, 102) 

ROW_NUMBER renvoie le numéro séquentiel d'une ligne dans une partition d'un set de résultats, en commençant à 1 pour la première ligne de chaque partition.

Un peu extrême mais puisqu'il faut utiliser deux fois IN (100, 101, 102) puis créer #temp

 CREATE TABLE #temp( [ID] [int] NOT NULL, [fname] [varchar](50) NOT NULL, [lname] [varchar](50) NOT NULL); insert into #temp([ID],[fname],[lname]) SELECT ID, FirstName, Surname FROM MyTable WHERE ID IN (100, 101, 102); select t1.ID, t2.count from #temp as t1 join ( select [fname],[lname], count(*) as count from #temp group by [fname],[lname] ) as t2 on t1.[fname] = t2.[fname] and t1.[lname] = t2.[lname]; 

La solution d'Alexander est probablement meilleure
Pour sûr c'est less de code