Friday, June 5, 2009

ROLLUP Ve Gruplamada toplama işlemleri

Bundan güzel ROLLUP anlatılmaz herhalde.
http://www.ianywhere.com/developer/product_manuals/sqlanywhere/0901/en/html/dbugen9/00000347.htm

WITH Test_Data AS (
SELECT 'Turkiye' AS country, 'bolge1' AS state, 'sabah' AS timing, 20 AS amount FROM dual UNION ALL
SELECT 'Turkiye' AS country, 'bolge1' AS state, 'aksam' AS timing, 30 AS amount FROM dual UNION ALL
SELECT 'Turkiye' AS country, 'bolge1' AS state, 'gece' AS timing, 12 AS amount FROM dual UNION ALL
SELECT 'Turkiye' AS country, 'bolge2' AS state, 'sabah' AS timing, 17 AS amount FROM dual UNION ALL
SELECT 'Turkiye' AS country, 'bolge2' AS state, 'aksam' AS timing, 13 AS amount FROM dual UNION ALL
SELECT 'Turkiye' AS country, 'bolge2' AS state, 'gece' AS timing, 20 AS amount FROM dual
)
SELECT country,
NVL(state, 'TOTAL') AS state,
timing,
SUM(amount) AS amount
FROM Test_Data
GROUP BY country, timing, ROLLUP(state)
ORDER BY state;
COUNTRY STATE TIMIN AMOUNT
------- ------ ----- ----------
Turkiye bolge1 aksam 30
Turkiye bolge1 gece 12
Turkiye bolge1 sabah 20
Turkiye bolge2 gece 20
Turkiye bolge2 aksam 13
Turkiye bolge2 sabah 17
Turkiye TOTAL gece 32
Turkiye TOTAL aksam 43
Turkiye TOTAL sabah 37

Burada ki sorguda bizden istenen bölge1 ve bölge2 nin zamana göre gruplandırılıp toplanması. bunun için ROLLUP komutunu kullanıyoruz. eğer burada NVL(state, 'TOTAL') AS state kullanmaz isek rollup ile üretilen satırlar boş gelecektir NVL burada boş yerleri istediğimiz değer ile dolduruyoruz.

ID SALARY CITY DESCRIPTION
---- ---------- ---------- ---------------
01 1234.56 Toronto Programmer
02 6661.78 Vancouver Tester
03 6544.78 Vancouver Tester
04 2344.78 Vancouver Manager
05 2334.78 Vancouver Tester
06 4322.78 New York Tester
07 7897.78 New York Manager
08 1232.78 Vancouver Tester

8 rows selected.

SQL>
SQL> SELECT city, description, SUM(salary)
2 FROM employee
3 GROUP BY ROLLUP(city, description);

CITY DESCRIPTION SUM(SALARY)
---------- --------------- -----------
Toronto Programmer 1234.56
Toronto 1234.56
New York Tester 4322.78
New York Manager 7897.78
New York 12220.56 -- new york şehrinin ara toplamı.
Vancouver Tester 16774.12 --vancouver şehrinde çalışan testerlerın genel toplamı
Vancouver Manager 2344.78
Vancouver 19118.9 --vancouver şehrinin genel toplamı
32574.02 -- bütün şehirlerin genel toplamı


Bu örnekte iki farklı değre göre grup toplamları alınıyor. GROUP BY ROLLUP(city, description); city once yazıldığı için city'e göre gruplanıyor.
yukarıdaki örnekde SUM(salary) kullandık bunun yerine AVG, MIN, MAX kullanabiliriz.

SELECT * FROM (
( SELECT A, B, C, SUM( D )
FROM T1
GROUP BY A, B, C )
UNION ALL
( SELECT A, B, NULL, SUM( D )
FROM T1
GROUP BY A, B )
UNION ALL
( SELECT A, NULL, NULL, SUM( D )
FROM T1
GROUP BY A )
UNION ALL
( SELECT NULL, NULL, NULL, SUM( D )FROM T1
)
)

bunun ile
SELECT A, B, C,
SUM( D )
FROM T1
GROUP BY ROLLUP
(A, B, C);
aynı işi yapıyor.

No comments: