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