Die Unterschiede zwischen CUBE und ROLLUP verstehen


70

Bei meiner Aufgabe wurde ich gebeten herauszufinden, wie viele Rechnungen für jedes Datum geschrieben wurden.

Ich steckte ein wenig fest und bat meinen Professor um Hilfe. Sie schickte mir eine E-Mail mit der Frage: "Wie viele Öfen jedes Typs und jeder Version wurden gebaut? Geben Sie für eine Herausforderung, aber ohne zusätzliche Punkte, die Gesamtzahl der Öfen an."

Dies war die Frage, die sie mir schickte:

SELECT STOVE.Type + STOVE.Version AS 'Type+Version'
, COUNT(*) AS 'The Count'
FROM STOVE
GROUP BY STOVE.Type + STOVE.Version WITH ROLLUP;

Also habe ich diese Abfrage optimiert, bis sie meinen Anforderungen entsprach. Folgendes habe ich mir ausgedacht:

SELECT InvoiceDt
, COUNT(InvoiceNbr) AS 'Number of Invoices' 
FROM INVOICE 
GROUP BY InvoiceDt WITH ROLLUP 
ORDER BY InvoiceDt ASC;

Und es gab die folgenden Ergebnisse zurück, die ich wollte.

Wie auch immer, ich entschied mich, die ROLLUP-Klausel zu lesen und begann mit einem Artikel von Microsoft . Die ROLLUP-Klausel ähnelte der CUBE-Klausel, unterschied sich jedoch folgendermaßen von der CUBE-Klausel:

  1. CUBE generiert eine Ergebnismenge, die Aggregate für alle Wertekombinationen in den ausgewählten Spalten anzeigt.
  2. ROLLUP generiert eine Ergebnismenge, die Aggregate für eine Wertehierarchie in den ausgewählten Spalten anzeigt.

Also habe ich beschlossen, das ROLLUP in meiner Abfrage durch CUBE zu ersetzen, um zu sehen, was passieren würde. Sie haben die gleichen Ergebnisse erzielt. Ich denke, dort werde ich verwirrt.

Wenn Sie die Art der Abfrage verwenden, die ich hier verwende, gibt es anscheinend keinen praktischen Unterschied zwischen den beiden Klauseln. Ist das richtig? Oder verstehe ich etwas nicht? Als ich mit dem Lesen des Microsoft-Artikels fertig war, hatte ich gedacht, dass meine Ergebnisse mit der CUBE-Klausel anders hätten sein sollen.

Antworten:


159

Sie werden keinen Unterschied feststellen, da Sie nur eine einzelne Spalte aufrollen. Betrachten Sie ein Beispiel, wo wir es tun

ROLLUP (YEAR, MONTH, DAY)

Mit a ROLLUPhat es die folgenden Ausgänge:

YEAR, MONTH, DAY
YEAR, MONTH
YEAR
()

Mit CUBEwird es folgendes haben:

YEAR, MONTH, DAY
YEAR, MONTH
YEAR, DAY
YEAR
MONTH, DAY
MONTH
DAY
()

CUBEEnthält im Wesentlichen jedes mögliche Rollup-Szenario für jeden Knoten ROLLUP, wobei die Hierarchie auf dem neuesten Stand bleibt (sodass der MONAT nicht übersprungen wird und JAHR / TAG angezeigt wird, während dies der Fall CUBEist).

Aus diesem Grund haben Sie keinen Unterschied festgestellt, da Sie nur eine einzige Spalte hatten, die Sie aufgerollt haben.

Hoffentlich hilft das.


3
Interessant. Ich frage mich, warum die Designer nicht einfach einen ausgewählt und einen zusätzlichen Attributparameter für das Verhalten hinzugefügt haben. Zwei verschiedene Namen für etwas zu haben, das im Grunde das Gleiche tut, aber etwas anders ist, ist ziemlich dumm.
mBrice1024

77

Wir können den Unterschied zwischen ROLLUP und CUBE anhand eines einfachen Beispiels verstehen. Stellen Sie sich vor, wir haben eine Tabelle, die die Ergebnisse der vierteljährlichen Tests der Schüler enthält. In bestimmten Fällen müssen wir die Summe sehen, die dem Quartal entspricht, sowie die Studenten. Hier ist die Beispieltabelle

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

Geben Sie hier die Bildbeschreibung ein

1. ROLLUP (Kann die Summe für eine Spalte finden)

(a) Erhalten Sie die Gesamtpunktzahl jedes Schülers in allen Quartalen.

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

Das Folgende ist das Ergebnis von (a)

Geben Sie hier die Bildbeschreibung ein

(b) Falls Sie die Gesamtpunktzahl für jedes Quartal erhalten müssen

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

Das Folgende ist das Ergebnis von (b)

Geben Sie hier die Bildbeschreibung ein

2. CUBE (Finden Sie die Summe für das Quartal sowie für die Schüler in einem einzigen Schuss)

SELECT PERIOD,NAME,SUM(MARKS) TOTAL
FROM #TEMP
GROUP BY NAME,PERIOD 
WITH CUBE
HAVING PERIOD IS NOT NULL OR NAME IS NOT NULL

Das Folgende ist das Ergebnis von CUBE

Geben Sie hier die Bildbeschreibung ein

Jetzt wundern Sie sich vielleicht über die Echtzeitverwendung von ROLLUP und CUBE. Manchmal brauchen wir einen Bericht, in dem wir die Summe jedes Quartals und die Summe jedes Schülers in einer einzigen Aufnahme sehen müssen. Hier ist ein Beispiel

Ich ändere die obige CUBE-Abfrage geringfügig, da wir für beide Summen eine Summe benötigen.

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

Jetzt erhalten Sie das folgende Ergebnis

Geben Sie hier die Bildbeschreibung ein


6

Dies liegt daran, dass Sie nur eine Spalte haben, nach der Sie gruppieren.

Hinzufügen Group by InvoiceDt, InvoiceCountry(oder ein beliebiges Feld, das Ihnen mehr Daten liefert.

Mit Cube erhalten Sie eine Summe für jedes InvoiceDt und Sie erhalten eine Summe für jedes InvoiceCountry.



0

Alle abgestimmten Antworten sind gut.


Ein wichtiger Unterschied im Allgemeinen ist

  1. Die N Elemente einer ROLLUP-Spezifikation entsprechen N + 1 GROUPING SETS.
  2. Die N Elemente einer CUBE-Spezifikation entsprechen 2 ^ N GROUPING SETS.

Weitere Informationen finden Sie in meinem Artikel zu Spark SQL

Zum Beispiel :

store_id, product_type

Rollup entspricht

GROUP BY store_id,product_type
 GROUPING SETS (
(store_id,product_type)
,(product_type)
, ())

für 2 (n) Gruppierung nach Spalten Gruppierungssatz hat (n + 1) = 3 Kombinationen von Spalten

Würfel entspricht

GROUP BY store_id,product_type
 GROUPING SETS (
(store_id,product_type)
,(store_id)
,(product_type)
, ())

für 2 (n) Gruppierung nach Spalten Gruppierungssatz hat (2 ^ n) = 4 Kombinationen von Spalten

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.