SQL Server – Comment supprimer certaines lignes de colonnes sans interrompre le rest de l'logging

I have it -- -- -- -- 01 A1 B1 99 01 A1 B1 98 02 A2 B2 97 02 A2 B2 96 I need this -- -- -- -- 01 A1 B1 99 98 02 A2 B2 97 96 ------------ 

Je ne peux pas répéter datatables que je vais présenter dans un excel, Mon résultat doit être juste. Dans mon tableau actuel, la dernière colonne est une réponse des formulaires et les premières colonnes (celles qui ne peuvent pas se répéter) sont datatables du client comme (téléphone, nom …). Le résultat final de cette «requête» remplira un «DataTable» et sera présenté dans un file «xlsx».

Merci de partager la connaissance ^^

Si vous avez SQL2012 +

 SELECT ISNULL(NULLIF(Column1,LAG(Column1) OVER(ORDER BY Column1)),'') ,ISNULL(NULLIF(Column2,LAG(Column2) OVER(ORDER BY Column1,Column2)),'') ,ISNULL(NULLIF(Column3,LAG(Column3) OVER(ORDER BY Column1,Column2,Column3)),'') ,Column4 FROM #mytable ORDER BY Column1,Column2,Column3,Column4 DESC 

C'est un peu désordonné, mais vous pouvez le faire dans la database. Vous créez essentiellement une sous-requête qui obtient la plus petite valeur, puis joignez-la à la table ordinaire et supprimez les valeurs qui ne correspondent pas. J'ai créé votre exemple comme ceci:

 CREATE TABLE mytable (N1 VARCHAR(2), A VARCHAR(2), B VARCHAR(2), N2 VARCHAR(2)) INSERT INTO mytable VALUES ('01', 'A1', 'B1', '99'), ('01', 'A1', 'B1', '98'), ('02', 'A2', 'B2', '97'), ('02', 'A2', 'B2', '96') 

Et puis a pu get le résultat comme ceci:

 SELECT CASE WHEN O.N2 = I.N2 THEN O.N1 ELSE '' END, CASE WHEN O.N2 = I.N2 THEN OA ELSE '' END, CASE WHEN O.N2 = I.N2 THEN OB ELSE '' END, O.N2 FROM (SELECT MAX(N2) AS N2, N1, A, B FROM mytable GROUP BY N1, A, B) I INNER JOIN mytable O ON OA = IA AND OB = IB AND O.N1 = I.N1 ORDER BY O.N1 ASC 

nous pouvons utiliser ROW_NUMBER pour get la séquence et replace '' pour toutes les lignes où la séquence est supérieure à 1

 with CTE AS ( SELECT ID, ColumnA, ColumnB, value,ROW_NUMBER() over ( PARTITION by id order by id) as seq FROM tableA ) , CTE1 AS ( select id, ColumnA, ColumnB, value, seq from CTE where seq =1 UNION SELECT id ,'','', value , seq from CTE where seq >1 ) SELECT case when seq >1 THEN NULL ELSE id END as id, columnA, columnB, value from CTE1 ( with CTE AS ( SELECT ID, ColumnA, ColumnB, value,ROW_NUMBER() over ( PARTITION by id order by id) as seq FROM tableA ) , CTE1 AS ( select id, ColumnA, ColumnB, value, seq from CTE where seq =1 UNION SELECT id ,'','', value , seq from CTE where seq >1 ) SELECT case when seq >1 THEN NULL ELSE id END as id, columnA, columnB, value from CTE1 

Vous pouvez get ce que vous voulez en utilisant une requête.

Vous n'avez pas fourni DDL, de sorte que je pense que vos colonnes sont appelées a , b , c et d respectivement

 ; WITH cte AS ( SELECT a , b , c , d , Row_Number() OVER (PARTITION BY a, b, c ORDER BY d) As sequence FROM your_table ) SELECT CASE WHEN sequence = 1 THEN a ELSE '' END As a , CASE WHEN sequence = 1 THEN b ELSE '' END As b , CASE WHEN sequence = 1 THEN c ELSE '' END As c , d FROM cte ORDER BY a , b , c , d ; ; WITH cte AS ( SELECT a , b , c , d , Row_Number() OVER (PARTITION BY a, b, c ORDER BY d) As sequence FROM your_table ) SELECT CASE WHEN sequence = 1 THEN a ELSE '' END As a , CASE WHEN sequence = 1 THEN b ELSE '' END As b , CASE WHEN sequence = 1 THEN c ELSE '' END As c , d FROM cte ORDER BY a , b , c , d 

L'idée est d'atsortingbuer un countur incrémental à chaque ligne, qui redémarre après chaque changement de a + b + c.

Nous utilisons ensuite une déclaration conditionnelle pour montrer une valeur ou non (uniquement dans la première instance de chaque groupe)

La fonction analytique ROW_NUMBER() est bonne pour cela. J'ai inventé des noms de colonnes parce que vous n'en avez rien fourni. Pour atsortingbuer un numéro de ligne par client, utilisez quelque chose comme ceci:

 SELECT Name, Phone, Address, Response, ROW_NUMBER() OVER (PARTITION BY Name, Phone, Address ORDER BY Response) AS CustRow FROM myTable 

Cela atsortingbuera le numéro de ligne dans chaque client. Essayez-le vous-même et je pense que cela aura du sens.

Vous pouvez le placer dans une sous-requête ou un CTE à partir de là et afficher uniquement les informations d'identification du client comme nom, téléphone et adresse lorsque vous êtes sur la première ligne pour chaque client:

 SELECT CASE WHEN CustRow = 1 THEN Name ELSE '' END AS Name, CASE WHEN CustRow = 1 THEN Phone ELSE '' END AS Phone, CASE WHEN CustRow = 1 THEN Address ELSE '' END AS Address, Response FROM ( SELECT Name, Phone, Address, Response, ROW_NUMBER() OVER (PARTITION BY Name, Phone, Address ORDER BY Response) AS CustRow FROM myTable) custSubquery ORDER BY Name, Phone, Address 

La custSubquery de la deuxième à la dernière ligne est parce que SQL Server exige que toutes les sous-requêtes soient alias, même si l'alias n'est pas utilisé.

Le plus important est de déterminer comment votre dernière colonne sera commandée pour l'affichage et de s'assurer qu'elle est cohérente dans la fonction ROW_NUMBER() ainsi que le ORDER BY final.

Si vous avez besoin de plus d'aide, veuillez fournir des noms de arrays et de colonnes et préciser comment les résultats sont commandés au sein de chaque client.