Mon travail m'a demandé de savoir "combien de factures sont écrites pour chaque date?"
J'étais un peu coincé et j'ai demandé l'aide de mon professeur. Elle m'a envoyé une requête qui répondrait à la question "Combien de poêles de chaque type et version ont été construits? Pour un défi mais pas de points en plus, incluez le nombre total de poêles."
Ce fut la requête qu'elle m'a envoyé:
SELECT STOVE.Type + STOVE.Version AS 'Type+Version'
, COUNT(*) AS 'The Count'
FROM STOVE
GROUP BY STOVE.Type + STOVE.Version WITH ROLLUP;
J'ai donc peaufiné cette requête jusqu'à ce qu'elle réponde à mes besoins. Voici ce que je suis venu avec:
SELECT InvoiceDt
, COUNT(InvoiceNbr) AS 'Number of Invoices'
FROM INVOICE
GROUP BY InvoiceDt WITH ROLLUP
ORDER BY InvoiceDt ASC;
Et cela a donné les résultats suivants que je voulais.
Quoi qu'il en soit, j'ai décidé de lire la clause ROLLUP et j'ai commencé avec un article de Microsoft . Il a déclaré que la clause ROLLUP était similaire à la clause CUBE, mais qu'elle se distinguait de la clause CUBE de la manière suivante:
J'ai donc décidé de remplacer ROLLUP dans ma requête par CUBE pour voir ce qui se passerait. Ils ont produit les mêmes résultats. Je suppose que c'est là que je deviens confus.
Il semble que si vous utilisez le type de requête que je suis ici, il n'y a pas de différence pratique entre les deux clauses. Est-ce correct? Ou est-ce que je ne comprends pas quelque chose? Lorsque j'avais fini de lire l'article de Microsoft, j'avais pensé que mes résultats auraient dû être différents avec la clause CUBE.
Vous ne verrez aucune différence puisque vous n’enroulez qu’une seule colonne. Prenons un exemple où nous faisons
ROLLUP (YEAR, MONTH, DAY)
Avec un ROLLUP
, il aura les sorties suivantes:
YEAR, MONTH, DAY
YEAR, MONTH
YEAR
()
Avec CUBE
, il aura les éléments suivants:
YEAR, MONTH, DAY
YEAR, MONTH
YEAR, DAY
YEAR
MONTH, DAY
MONTH
DAY
()
CUBE
contient essentiellement tous les scénarios de cumul possibles pour chaque nœud alors que ROLLUP
gardera la hiérarchie intacte (pour ne pas ignorer MONTH et afficher YEAR/DAY, alors que CUBE
)
C'est pourquoi vous n'avez pas vu de différence puisque vous n'aviez qu'une seule colonne à remonter.
J'espère que ça t'as aidé.
Nous pouvons comprendre la différence entre ROLLUP et CUBE avec un exemple simple. Considérons que nous avons un tableau qui contient les résultats du test trimestriel des étudiants. Dans certains cas, nous avons besoin de voir le total correspondant au trimestre et aux étudiants. Voici le tableau échantillon
SELECT * INTO #TEMP
FROM
(
SELECT 'Quarter 1' PERIOD,'Amar' NAME ,97 MARKS
UNION ALL
SELECT 'Quarter 1','Ram',88
UNION ALL
SELECT 'Quarter 1','Simi',76
UNION ALL
SELECT 'Quarter 2','Amar',94
UNION ALL
SELECT 'Quarter 2','Ram',82
UNION ALL
SELECT 'Quarter 2','Simi',71
UNION ALL
SELECT 'Quarter 3' ,'Amar',95
UNION ALL
SELECT 'Quarter 3','Ram',83
UNION ALL
SELECT 'Quarter 3','Simi',77
UNION ALL
SELECT 'Quarter 4' ,'Amar',91
UNION ALL
SELECT 'Quarter 4','Ram',84
UNION ALL
SELECT 'Quarter 4','Simi',79
)TAB
1. ROLLUP (Peut trouver le total correspondant à une colonne)
(a) Obtenez le score total de chaque élève dans tous les trimestres.
SELECT * FROM #TEMP
UNION ALL
SELECT PERIOD,NAME,SUM(MARKS) TOTAL
FROM #TEMP
GROUP BY NAME,PERIOD
WITH ROLLUP
HAVING PERIOD IS NULL AND NAME IS NOT NULL
// Having is used inorder to emit a row that is the total of all totals of each student
Voici le résultat de (a)
(b) Si vous avez besoin d'obtenir le score total de chaque trimestre
SELECT * FROM #TEMP
UNION ALL
SELECT PERIOD,NAME,SUM(MARKS) TOTAL
FROM #TEMP
GROUP BY PERIOD,NAME
WITH ROLLUP
HAVING PERIOD IS NOT NULL AND NAME IS NULL
Voici le résultat de (b)
2. CUBE (Trouver le total pour le trimestre et les étudiants en un seul coup)
SELECT PERIOD,NAME,SUM(MARKS) TOTAL
FROM #TEMP
GROUP BY NAME,PERIOD
WITH CUBE
HAVING PERIOD IS NOT NULL OR NAME IS NOT NULL
Voici le résultat de CUBE
Maintenant, vous vous demandez peut-être comment utiliser ROLLUP et CUBE en temps réel. Parfois, nous avons besoin d'un rapport dans lequel nous devons voir le total de chaque trimestre et le total de chaque élève en un seul coup. Voici un exemple
Je modifie légèrement la requête CUBE ci-dessus, car nous avons besoin du total pour les deux totaux.
SELECT CASE WHEN PERIOD IS NULL THEN 'TOTAL' ELSE PERIOD END PERIOD,
CASE WHEN NAME IS NULL THEN 'TOTAL' ELSE NAME END NAME,
SUM(MARKS) MARKS
INTO #TEMP2
FROM #TEMP
GROUP BY NAME,PERIOD
WITH CUBE
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + PERIOD + ']',
'[' + PERIOD + ']')
FROM (SELECT DISTINCT PERIOD FROM #TEMP2) PV
ORDER BY PERIOD
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM
(
SELECT * FROM #TEMP2
) x
PIVOT
(
SUM(MARKS)
FOR [PERIOD] IN (' + @cols + ')
) p;'
EXEC SP_EXECUTESQL @query
Maintenant, vous obtiendrez le résultat suivant
En effet, vous ne regroupez qu'une colonne.
Ajouter Group by InvoiceDt, InvoiceCountry
_ (ou quel que soit le champ qui vous donnera plus de données.
Avec Cube, vous obtiendrez une somme pour chaque InvoiceDt et vous obtiendrez une somme pour chaque InvoiceCountry.
Vous pouvez trouver plus de détails sur GROUPING SET, CUBE, ROLL UP. TL; DR, ils développent simplement GROUP BY + UNION ALL de manière à obtenir l’agrégation :)
https://technet.Microsoft.com/en-us/library/bb510427 (v = sql.105) .aspx