Grouping Sets در sql server 2008
این نسخه از SQL Server چندین پسوند برای Group By معرفی کرده که به شما این امکان را میدهد که به صورت همزمان چندین عملیات Grouping روی یک query داشته باشید. این پسوندها عبارتند از Grouping Sets و CUBE و ROLLUP که زیرعبارتهایی از عبارت Group By و توابع GROUPING_ID هستند. پسوندهای جدید استاندارد هستند و نباید با option های غیراستاندارد و قدیمی CUBE و ROLLUP اشتباه گرفته شوند.
زیر عبارات GROUPING SETS و CUBE و ROLLUP
برای نمایش و معرفی این عبارات اجازه دهید به چند تکه کد اشاره کنیم:
USE tempdb;
IF OBJECT_ID('dbo.Orders', 'U') IS NOT NULL DROP TABLE dbo.Orders;
CREATE TABLE dbo.Orders
(
orderid INT NOT NULL,
orderdate DATETIME NOT NULL,
empid INT NOT NULL,
custid VARCHAR(5) NOT NULL,
qty INT NOT NULL,
CONSTRAINT PK_Orders PRIMARY KEY(orderid)
);
INSERT INTO dbo.Orders (orderid, orderdate, empid, custid, qty)
VALUES
(30001, '20060802', 3, 'A', 10), (10001, '20061224', 1, 'A', 12),
(10005, '20061224', 1, 'B', 20), (40001, '20070109', 4, 'A', 40),
(10006, '20070118', 1, 'C', 14), (20001, '20070212', 2, 'B', 12),
(40005, '20080212', 4, 'A', 10), (20002, '20080216', 2, 'C', 20),
(30003, '20080418', 3, 'B', 15), (30004, '20060418', 3, 'C', 22),
(30007, '20060907', 3, 'D', 30);
بدون پسوندها یک query به صورت نرمال فقط یک Grouping Set در عبارت Group By تعریف میکند. اگر شما بخواهید یک aggregate را روی چندین مجموعه از گروهها اعمال کنید شما به چندینquery نیاز خواهید داشت. و برای اینکه نتیجه را به صورت یکجا داشته باشید مجبور هستید که از UNION ALL استفاده نمایید.
با زیرعبارت جدید Grouping Sets شما به سادگی میتوانید تمام گروههایی را که میخواهید لیست کنید. به صورت منطقی شما دارید همان کار قدیم را انجام میدهید و نتیجه چندین query را یکی میکنید. البته شما با این روش دسترسی به داده و میزان محاسبات را بهینه میکنید. این بدین دلیل است که SQL SERVER به ازای هر مجموعه نیاز ندارد که داده ها را پیمایش کند، به علاوه در برخی موارد آن یک aggregate سطح بالاتر را بر اساس یک aggregate سطح پایینتر محاسبه میکند به جای اینکه دوباره داده های پایه را محاسبه کند.
به عنوان مثال، query زیر روی چهار مجموعه عملیات aggregate را انجام میدهد :
SELECT custid, empid, YEAR(orderdate) AS orderyear, SUM(qty) AS qty
FROM dbo.Orders
GROUP BY GROUPING SETS (
( custid, empid, YEAR(orderdate) ),
( custid, YEAR(orderdate) ),
( empid, YEAR(orderdate) ),
() );
چهار سطر آخر مجموعه های تعریف شده هستند. آخرین آنها یعنی () یا مجموعه خالی جایگزین ALL یعنی همه میشود. این مانند یک aggregate query بدون عبارت GROUP BY است که شما با تمام جدول مانند یک گروه واحد رفتار کردید.
دو زیر عبارت جدید دیگر باید به عنوان مخفف در زیر عبارت Grouping Sets به کار روند. زیرعبارت CUBE یک مجموعه قدرتمند از مجموعه المانهای لیست شده در پرانتزها تولید میکند. به عبارت دیگر، این تمام مجموعه گروههای ممکن که میتوان با عناصر لیست شده در پرانتزها ساخته شود را تولید میکند که شما مجموعه خالی نیز میشود. به عنوان مثال استفاده زیر از CUBE :
منطقا معادل است با :
GROUPING SETS((a),(b),(c),(a, b),(a, c),(b, c),(a, b, c),())
برای n عنصر CUBE به ادازه 2 به توان n مجموعه گروه میسازد.
خارج از عناصر لیست شده در پرانتزها، زیرعبارت ROLLUP تنها مجموعه گروههایی را تولید میکند که دارای business value باشند، وراثت و سلسله مراتب را بین عناصر فرض کنید. به عنوان مثال استفاده زیر از ROLLUP :
ROLLUP( country, region, city )
منطقا معادل است با :
GROUPING SETS((country, region, city),(country, region),(country),())
دقت کنید مواردی که دارای business value نیستند، سلسله مراتب را بین عناصر فرض کنید- مانند (city) تولید نشده اند.ممکن است چندین شهر با یک نام در دنیا موجود باشد حتی ممکن است در یک کشور شهر همنام موجود باشد بنابراین هیچ business value برای اینکه آنها را مجتمع کنیم موجود نیست.