Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Utilisation d'un tableau croisé dynamique avec des totaux de colonnes et de lignes dans SQL Server 2008

Il peut y avoir différentes approches à cela. Vous pouvez calculer tous les totaux après le pivot, ou vous pouvez d'abord obtenir les totaux, puis faire pivoter tous les résultats. Il est également possible d'avoir une sorte de terrain d'entente :obtenir un type de totaux (par exemple, les totaux par ligne), pivoter, puis obtenir l'autre type, bien que cela puisse exagérer.

La première des approches mentionnées, obtenir tous les totaux après le pivot, pourrait être effectuée de manière très simple, et la seule chose potentiellement nouvelle pour vous dans l'implémentation ci-dessous pourrait être GROUP BY ROLLUP() :

SELECT
  [ ]      = ISNULL(environment_name, 'Total'),
  [Enviro] = SUM([Enviro]),
  [Requi]  = SUM([Requi]),
  [Dev]    = SUM([Dev]),
  [Tsc]    = SUM([Tsc]),
  [TD]     = SUM([TD]),
  [Unkn]   = SUM([Unkn]),
  Total    = SUM([Enviro] + [Requi] + [Dev] + [Tsc] + [TD] + [Unkn])
FROM (
  SELECT environment_name, root_cause
  FROM test1
) s
PIVOT (
  COUNT(root_cause)
  FOR root_cause IN ([Enviro], [Requi], [Dev], [Tsc], [TD], [Unkn])
) p
GROUP BY
  ROLLUP(environment_name)
;

Fondamentalement, le GROUP BY ROLLUP() la partie produit la ligne totale pour toi. Le regroupement est d'abord effectué par environment_name , la ligne de total général est ajoutée.

Pour faire exactement le contraire, c'est-à-dire obtenir les totaux avant de pivoter, vous pouvez utiliser GROUP BY CUBE() comme ceci :

SELECT
  [ ]      = environment_name,
  [Enviro] = ISNULL([Enviro], 0),
  [Requi]  = ISNULL([Requi] , 0),
  [Dev]    = ISNULL([Dev]   , 0),
  [Tsc]    = ISNULL([Tsc]   , 0),
  [TD]     = ISNULL([TD]    , 0),
  [Unkn]   = ISNULL([Unkn]  , 0),
  Total    = ISNULL(Total   , 0)
FROM (
  SELECT
    environment_name = ISNULL(environment_name, 'Total'),
    root_cause       = ISNULL(root_cause,       'Total'),
    cnt              = COUNT(*)
  FROM test1
  WHERE root_cause IS NOT NULL
  GROUP BY
    CUBE(environment_name, root_cause)
) s
PIVOT (
  SUM(cnt)
  FOR root_cause IN ([Enviro], [Requi], [Dev], [Tsc], [TD], [Unkn], Total)
) p
;

Les deux méthodes peuvent être testées et jouées avec SQL Fiddle :

Remarque. J'ai omis l'étape de non pivotement dans les deux suggestions car le fait de ne pas pivoter une seule colonne semblait clairement redondant. S'il y a plus, cependant, ajuster l'une ou l'autre des requêtes devrait être facile.