Понимание различий между CUBE и ROLLUP - PullRequest
61 голосов
/ 14 августа 2011

Мое задание попросило меня выяснить, «сколько счетов написано на каждую дату?»

Я немного застрял и попросил моего профессора о помощи. Она послала мне по электронной почте запрос, который ответил бы на вопрос: «Сколько печей каждого типа и версии было построено? За вызов, но без дополнительных очков, укажите общее количество печей. "

Это был запрос, который она прислала мне:

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

Итак, я настраивал этот запрос, пока он не отвечал моим потребностям. Вот что я придумал:

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

И он вернул следующие результаты, которые я хотел.

В любом случае, я решил прочитать предложение ROLLUP и начал со статьи Microsoft . В нем говорится, что предложение ROLLUP аналогично предложению CUBE, но отличается от предложения CUBE следующим образом:

  1. CUBE генерирует результирующий набор, который показывает агрегаты для всех комбинаций значений в выбранных столбцах.
  2. ROLLUP генерирует набор результатов, который показывает агрегаты для иерархии значений в выбранных столбцах.

Итак, я решил заменить ROLLUP в моем запросе на CUBE, чтобы посмотреть, что произойдет. Они дали те же результаты. Я думаю, вот где я запутался.

Похоже, если вы используете тип запроса, который я здесь, что между этими двумя предложениями нет никакой практической разницы. Это правильно? Или я чего-то не понимаю? Когда я закончил читать статью Microsoft, я думал, что мои результаты должны были отличаться при использовании предложения CUBE.

Ответы [ 4 ]

145 голосов
/ 14 августа 2011

Вы не увидите никакой разницы, поскольку вы свернете только один столбец.Рассмотрим пример, в котором мы делаем

ROLLUP (YEAR, MONTH, DAY)

При ROLLUP он будет иметь следующие выходные данные:

YEAR, MONTH, DAY
YEAR, MONTH
YEAR
()

При CUBE он будетимеют следующее:

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

CUBE по существу содержит все возможные сценарии свертки для каждого узла, тогда как ROLLUP будет держать иерархию в такте (поэтому не будет пропускать MONTH и показывать YEAR / DAY, тогда какCUBE будет)

Вот почему вы не видели разницы, поскольку у вас был только один столбец, который вы свернули.

Надеюсь, это поможет.

74 голосов
/ 01 декабря 2014

Мы можем понять разницу между ROLLUP и CUBE на простом примере.Предположим, у нас есть таблица, в которой содержатся результаты ежеквартального тестирования студентов.В некоторых случаях мы должны видеть общее количество, соответствующее кварталу, а также студентов.Вот пример таблицы

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

enter image description here

1.ROLLUP (можно найти общее количество для соответствующего одного столбца)

(a) Получить общий балл каждого студента за все кварталы.

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

Ниже приводится результат (a)

enter image description here

(b) Если вам необходимо получить общий балл за каждый квартал

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

Ниже приведен результат (b)

enter image description here

2.CUBE (Найти сумму за четверть, а также студентов за один выстрел)

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

Ниже приводится результат CUBE

enter image description here

Теперь вы можете задаться вопросом об использовании ROLLUP и CUBE в реальном времени.Иногда нам нужен отчет, в котором нам нужно увидеть итоговую оценку каждого квартала и итоговую оценку каждого студента за один раз.Вот пример

Я слегка изменяю вышеупомянутый запрос CUBE, так как нам нужно общее значение для обоих итогов.

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

Теперь вы получите следующий результат

enter image description here

6 голосов
/ 14 августа 2011

Это потому, что у вас есть только один столбец, по которому вы группируете.

Добавить Group by InvoiceDt, InvoiceCountry (или любое другое поле, которое даст вам больше данных.

С помощью Cube вы получите сумму для каждого InvoiceDt, и вы получите сумму для каждого InvoiceCountry.

1 голос
/ 04 января 2017

Вы можете найти более подробную информацию о наборе групп, куб, свернуть.TL; DR они просто расширяют GROUP BY + UNION ALL некоторым образом, чтобы получить агрегацию:)

https://technet.microsoft.com/en-us/library/bb510427(v=sql.105).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...