Combiner GROUP BY et ROW_NUMBER ()

ECHANTILLONNAGE

userid email_address login_name name Title org phone_number_com ============= ========================== =============== ================== ========== ============= =================== 1192 [email protected] sjobs Steve Jobs CEO Apple N/A 1274 [email protected] sjobs Steve Jobs CFO Apple 697-4686 1192 [email protected] sjobs Steven jobs CEO Apple 604-7126 1885 [email protected] bgates Bill Gates CEO Microsoft 604-7114 1920 [email protected] bgates William Gates CTR Microsoft 604-7247 1951 [email protected] wbuffet Warren Buffet CEO HP 614-9141 1954 [email protected] wbuffet W. Buffet COO HP 614-7589 1951 [email protected] wbuffet Warren S Buffet CIO Xerox 614-8874 1956 [email protected] mzuck Mark Zuckerberg CEO FB 614-8295 

QUESTION

 SELECT * FROM ( SELECT userid, name, login_name, email_address, phone_number_com, ROW_NUMBER() OVER(PARTITION BY [login_name] ORDER BY login_name) Num_Duplicates FROM web_user ) as Rows WHERE Num_Duplicates > 1 

C'est mon premier post, j'espère suivre toutes les procédures. Je reçois un jeu de résultats qui affiche les 2ème et 3ème lignes qui sont dupliquées. login_name de GROUP BY login_name et affiche seulement la ligne avec le Num_Duplicates le plus Num_Duplicates . Si un login_name a un Num_Duplicates de 2 et 3, afficher seulement la ligne avec 3. J'espère que cela a du sens! Merci d'avance pour toute orientation que vous pouvez fournir.

CES RÉSULTATS JE VOUDRAIS QUE LA DEMANDE POUR SORTIR:

 userid | email_address | login_name | name | Title | org phone_number_com | Num_Duplicates 1192 | [email protected] | sjobs | Steve Jobs | CEO | Apple | N/A | 3 1885 | [email protected] | bgates | Bill Gates | CEO | Microsoft | 604-7114 | 2 1951 | [email protected] | wbuffet | Warren Buffet | CEO | HP | 614-9149 | 3 

Hmm – à partir de votre description, on dirait que vous voulez simplement quelque chose comme ça (sur le dessus de ma tête):

 SELECT login_name, email_address FROM web_user GROUP BY login_name, email_address HAVING count(*) > 2 

Si je comprends ce que vous essayez de faire correctement, vous devez d'abord le grouper par nom de connection pour get le nombre de duplicates:

 SELECT login_name, COUNT(*) AS num_duplicates FROM web_user GROUP BY login_name 

Ici vous pouvez soit utiliser une sous-requête avec ROW_NUMBER() (bien que je reorderais d'utiliser RANK() en cas de liens) ou vous pouvez simplement utiliser l'agrégat dans la fonction de la window:

 SELECT login_name, COUNT(*) AS num_duplicates , RANK() OVER ( ORDER BY COUNT(*) DESC ) AS rn FROM web_user GROUP BY login_name; 

alors mettez ceci dans une sous-requête pour get seulement le login_name avec le plus de duplicates:

 SELECT * FROM ( SELECT login_name, COUNT(*) AS num_duplicates , RANK() OVER ( ORDER BY COUNT(*) DESC ) AS rn FROM web_user GROUP BY login_name ) WHERE rn = 1; 

MISE À JOUR par les commentaires du PO, modifications de questions:

 SELECT userid, name, login_name, email_address, phone_number_com, num_duplicates FROM ( SELECT userid, name, login_name, email_address, phone_number_com , COUNT(*) OVER ( PARTITION BY login_name ) AS num_duplicates , ROW_NUMBER() OVER ( PARTITION BY login_name ORDER BY userid ) AS rn FROM web_user ) WHERE num_duplicates > 1 AND rn = 1; 

Ce que je fais ci-dessus utilise COUNT(*) comme une fonction de window; le partitionnement par login_name obtiendra le count pour chaque nom de connection. Je partitionne aussi par login_name pour get ROW_NUMBER() et ordonne par userid afin que je puisse returnner la valeur minimum (que vous semblez faire dans la sortie désirée).

Ce qui suit devrait vous donner ce dont vous avez besoin.

La fonction de window ROW_NUMBER est utilisée pour identifier la première ligne d'un nom de connection.

La fonction de la window COUNT est utilisée pour countr le nombre de lignes par login_name.

La requête externe restreint alors les résultats à ceux nom_login qui ont plus de 1 ligne et uniquement la première ligne pour chaque nom_login est renvoyée.

 DECLARE @users TABLE ( userid int , email_address varchar(100) , login_name varchar(100) , name varchar(100) , title varchar(100) , org varchar(100) , phone_number_com varchar(100) ) INSERT INTO @users VALUES (1192, '[email protected]', 'sjobs', 'Steve Jobs', 'CEO', 'Apple', 'N/A') , (1274, '[email protected]', 'sjobs', 'Steve Jobs', 'CFO', 'Apple', '697-4686') , (1192, '[email protected]', 'sjobs', 'Steven jobs', 'CEO', 'Apple', '604-7126') , (1885, '[email protected]', 'bgates', 'Bill Gates', 'CEO', 'Microsoft', '604-7114') , (1920, '[email protected]', 'bgates', 'William Gates', 'CTR', 'Microsoft', '604-7247') , (1951, '[email protected]', 'wbuffet', 'Warren Buffet', 'CEO', 'HP', '614-9141') , (1954, '[email protected]', 'wbuffet', 'W. Buffet', 'COO', 'HP', '614-7589') , (1951, '[email protected]', 'wbuffet', 'Warren S Buffet', 'CIO', 'Xerox', '614-8874') , (1956, '[email protected]', 'mzuck', 'Mark Zuckerberg', 'CEO', 'FB', '614-8295') ; WITH LoginWithWindowFunction AS ( SELECT * , ROW_NUMBER() OVER(PARTITION BY login_name ORDER BY userid) AS LoginOrder , COUNT(*) OVER(PARTITION BY login_name) AS Num_Duplicates FROM @users ) SELECT userid , email_address , login_name , name , title , org , phone_number_com , Num_Duplicates FROM LoginWithWindowFunction WHERE LoginOrder = 1 AND Num_Duplicates > 1 ORDER BY userid