örnek yapabileceğimiz ortamı hazırlayalım.
CREATE TABLE TTEST
(
IDX CHAR(15 BYTE),
AD VARCHAR2(20 BYTE),
TUTAR NUMBER(18,2),
STATUS CHAR(1 BYTE),
TARIH DATE
);
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200902261503189’, ‘SAD’, 14, ‘W’, TO_DATE(’02/26/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200901191507200’, ‘AHM’, 42, ‘W’, TO_DATE(’01/19/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, TARIH) Values (‘200901191505633’, ‘SAL’, 32, TO_DATE(’01/19/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200902261506519’, ‘AAT’, 20, ‘N’, TO_DATE(’02/26/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200902261508282’, ‘SUL’, 10, ‘N’, TO_DATE(’02/26/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200903031534449’, ‘CAN’, 16, ‘N’, TO_DATE(’03/03/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200903031534950’, ‘KEM’, 35, ‘N’, TO_DATE(’03/03/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200903031534721’, ‘ERM’, 12, ‘N’, TO_DATE(’03/03/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200901191509347’, ‘PET’, 15, ‘N’, TO_DATE(’01/19/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
Insert into TTEST (IDX, AD, TUTAR, STATUS, TARIH) Values (‘200901191507345’, ‘ONU’, 30, ‘N’, TO_DATE(’01/19/2009 00:00:00′, ‘MM/DD/YYYY HH24:MI:SS’));
COMMIT;
***************************************************************************
NTILE belirtilen sayıya göre kayıt grublaması yapar. mesela 100 kayıt varsa 10ar 10ar işaretleme yapar
Select IDX,TARIH TARIH,TUTAR,NTILE(5) OVER (ORDER BY TUTAR) AS TILE4 FROM ttest;
IDX TARIH TUTAR TILE4
–
200902261508282 26-ŞUB-09 10 1
200903031534721 03-MAR-09 12 1
200902261503189 26-ŞUB-09 14 2
200901191509347 19-OCA-09 15 2
200903031534449 03-MAR-09 16 3
200902261506519 26-ŞUB-09 20 3
200901191507345 19-OCA-09 30 4
200901191505633 19-OCA-09 32 4
200903031534950 03-MAR-09 35 5
200901191507200 19-OCA-09 42 5
***************************************************************************
ROW_NUMBER sıralı bi şekilde numara verir. Ornekte gozuktugu uzere tarih kayit kümesine gore her satira ardisik numara verdi.
Select IDX,TARIH,TUTAR,ROW_NUMBER() OVER (PARTITION BY TARIH ORDER BY TUTAR DESC) NUM FROM ttest;
IDX TARIH TUTAR NUM
–
200901191507200 19-OCA-09 42 1
200901191505633 19-OCA-09 32 2
200901191507345 19-OCA-09 30 3
200901191509347 19-OCA-09 15 4
200902261506519 26-ŞUB-09 20 1
200902261503189 26-ŞUB-09 14 2
200902261508282 26-ŞUB-09 10 3
200903031534950 03-MAR-09 35 1
200903031534449 03-MAR-09 16 2
200903031534721 03-MAR-09 12 3
***************************************************************************
RANK() belirtilen kurallara göre sıralama yapar ve numaralandırır, aynı degerlere aynı dank’i verdigi icin ardisik olmayabilir.
Örnekte görüldüğü gibi aynı degerde 3 satıra 1, 4. satira 4 deyip devam ediyor.
select IDX, TARIH, TUTAR, RANK() OVER(ORDER BY TARIH DESC) NUM from ttest;
IDX TARIH TUTAR NUM
–
200903031534449 03-MAR-09 16 1
200903031534721 03-MAR-09 12 1
200903031534950 03-MAR-09 35 1
200902261506519 26-ŞUB-09 20 4
200902261503189 26-ŞUB-09 14 4
200902261508282 26-ŞUB-09 10 4
200901191505633 19-OCA-09 32 7
200901191507200 19-OCA-09 42 7
200901191509347 19-OCA-09 15 7
200901191507345 19-OCA-09 30 7
***************************************************************************
DENSE_RANK() belirtilen kurallara göre sıralama yapar ve numaralandırır. RANK’a cok benzer, ardisik siralama vardir
select IDX, TARIH, TUTAR, DENSE_RANK() OVER(PARTITION BY TARIH ORDER BY TUTAR DESC) NUM from ttest;
IDX TARIH TUTAR NUM
–
200901191507200 19-OCA-09 42 1
200901191505633 19-OCA-09 32 2
200901191507345 19-OCA-09 30 3
200901191509347 19-OCA-09 15 4
200902261506519 26-ŞUB-09 20 1
200902261503189 26-ŞUB-09 14 2
200902261508282 26-ŞUB-09 10 3
200903031534950 03-MAR-09 35 1
200903031534449 03-MAR-09 16 2
200903031534721 03-MAR-09 12 3
***************************************************************************
NULLS LAST/FIRST ile nullları alta veya basa alabiliriz. Ornekte de goruldugu gibi tek null satisi sona alindi
select IDX, TARIH, TUTAR, STATUS, RANK() OVER(ORDER BY STATUS DESC NULLS LAST) NUM from ttest;
IDX TARIH TUTAR S NUM
– –
200902261503189 26-ŞUB-09 14 W 1
200901191507200 19-OCA-09 42 W 1
200902261508282 26-ŞUB-09 10 N 3
200902261506519 26-ŞUB-09 20 N 3
200901191507345 19-OCA-09 30 N 3
200903031534449 03-MAR-09 16 N 3
200903031534950 03-MAR-09 35 N 3
200903031534721 03-MAR-09 12 N 3
200901191509347 19-OCA-09 15 N 3
200901191505633 19-OCA-09 32 10
***************************************************************************
ROWS UNBOUNDED PRECEDING belirtilen kayıt kümesi içinde başlangıç satırından o anki satira kadar işlem yapar. Bu kural defaulttur, Yani ayrıca belirtilmesine gerek yok
select IDX, TARIH, TUTAR, SUM(TUTAR) OVER (PARTITION BY TARIH ORDER BY IDX) SSUM from ttest; da ayni sonucu verir
Ornekte de goruldugu gibi 32, 32+42, 32+42+30, … seklinde ilerliyor
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING = baslangic satirindan son satira kadar islem yaparar.
Fakat bu amac için bu kullanisli degildir. Cunklu ROWS komutunu kullanmazsak ayni islemi yapar. Bu amaç için RANGE BETWEEN komutunu kullanmak daha mantiklidir.
select IDX, TARIH, TUTAR, SUM(TUTAR) OVER (PARTITION BY TARIH ORDER BY IDX ROWS UNBOUNDED PRECEDING) SSUM from ttest;
IDX TARIH TUTAR SSUM
–
200901191505633 19-OCA-09 32 32
200901191507200 19-OCA-09 42 74
200901191507345 19-OCA-09 30 104
200901191509347 19-OCA-09 15 119
200902261503189 26-ŞUB-09 14 14
200902261506519 26-ŞUB-09 20 34
200902261508282 26-ŞUB-09 10 44
200903031534449 03-MAR-09 16 16
200903031534721 03-MAR-09 12 28
200903031534950 03-MAR-09 35 63
ayni ozellikle SUM yerine MAX MIN AVG COUNT de yazilabilirdi
burada dikkat edilmesi gereken ORDER BY kullanmazsak kayit kumesinin tamaminin goze alinması, kullanirsak current row’a kadar kayit kumesinin goze alinmasi
MAX -> select IDX, TARIH, TUTAR, MAX(TUTAR) OVER (PARTITION BY TARIH ORDER BY IDX) x from ttest;
COUNT -> select IDX, TARIH, TUTAR, COUNT(1) over (partition by TARIH) CCNT from ttest;
***************************************************************************
RANGE BETWEEN belirli araliktaki satirlara gore islem yapilabilir
Ornekte tam anlasilmasa da ilk kayit grubu icin 20091119 tarihinden bi onceki ve sonraki gun’e sahip kayitlar degerlendiriliyor. 20091118 ve 20091120 olsaydi onlar da AVG ye katilacakti.
Select IDX, TARIH, TUTAR, AVG(TUTAR) OVER (ORDER BY to_date(TARIH,’YYYYmmdd’) RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) ORT from ttest; Asagidaki ornek interval kullanilmadan yazilabilirdi.
Select IDX, TARIH, TUTAR, AVG(TUTAR) OVER (ORDER BY TARIH RANGE BETWEEN INTERVAL ‘1’ DAY PRECEDING AND INTERVAL ‘1’ DAY FOLLOWING) ORT from ttest;
IDX TARIH TUTAR ORT
–
200901191509347 19-OCA-09 15 29.75
200901191507345 19-OCA-09 30 29.75
200901191505633 19-OCA-09 32 29.75
200901191507200 19-OCA-09 42 29.75
200902261506519 26-ŞUB-09 20 14.6666667
200902261503189 26-ŞUB-09 14 14.6666667
200902261508282 26-ŞUB-09 10 14.6666667
200903031534721 03-MAR-09 12 21
200903031534449 03-MAR-09 16 21
200903031534950 03-MAR-09 35 21
Select IDX, TARIH, TUTAR, SUM(TUTAR) OVER (ORDER BY TARIH RANGE BETWEEN INTERVAL ’10’ DAY PRECEDING AND CURRENT ROW) SSUM from ttest; CURRENT ROW bulunulan satira kadar demektir
***************************************************************************
ROWS x PRECEDING , x satir geriye giderek islem yapar
Ornekte goruzludugu gibi, ilk kayit grubuna gore 32, 32 +42, 32+42+30, 42+30+15, daha sonra diger katir grubuna geciyor.
select IDX, TARIH, TUTAR, SUM(TUTAR) OVER (PARTITION BY TARIH ORDER BY IDX ROWS 2 PRECEDING) SSUM from ttest;
IDX TARIH TUTAR SSUM
–
200901191505633 19-OCA-09 32 32
200901191507200 19-OCA-09 42 74
200901191507345 19-OCA-09 30 104
200901191509347 19-OCA-09 15 87
200902261503189 26-ŞUB-09 14 14
200902261506519 26-ŞUB-09 20 34
200902261508282 26-ŞUB-09 10 44
200903031534449 03-MAR-09 16 16
200903031534721 03-MAR-09 12 28
200903031534950 03-MAR-09 35 63
***************************************************************************
RATIO_TO_REPORT belirtilen degerin belirtilen satir kümesindeki orani verir
select IDX, TARIH, TUTAR, RATIO_TO_REPORT(TUTAR) OVER (PARTITION BY TARIH) ORAN from ttest;
IDX TARIH TUTAR ORAN
–
200901191509347 19-OCA-09 15 .126050420
200901191507345 19-OCA-09 30 .252100840
200901191505633 19-OCA-09 32 .268907563
200901191507200 19-OCA-09 42 .352941176
200902261506519 26-ŞUB-09 20 .454545455
200902261503189 26-ŞUB-09 14 .318181818
200902261508282 26-ŞUB-09 10 .227272727
200903031534721 03-MAR-09 12 .190476190
200903031534449 03-MAR-09 16 .253968254
200903031534950 03-MAR-09 35 .555555556
***************************************************************************
LAG belirtilen alanin onceki satirdaki degerini verir
select IDX, TARIH, TUTAR, LAG(TUTAR,1) OVER (ORDER BY IDX) PREVIOUS_VALUE from ttest;
IDX TARIH TUTAR PREVIOUS_VALUE
–
200901191505633 19-OCA-09 32
200901191507200 19-OCA-09 42 32
200901191507345 19-OCA-09 30 42
200901191509347 19-OCA-09 15 30
200902261503189 26-ŞUB-09 14 15
200902261506519 26-ŞUB-09 20 14
200902261508282 26-ŞUB-09 10 20
200903031534449 03-MAR-09 16 10
200903031534721 03-MAR-09 12 16
200903031534950 03-MAR-09 35 12
***************************************************************************
LEAD belirtilen alanin sonraki satirdaki degerini verir
select IDX, TARIH, TUTAR, LEAD(TUTAR,1) OVER (ORDER BY IDX) NEXT_VALUE from ttest;
IDX TARIH TUTAR NEXT_VALUE
–
200901191505633 19-OCA-09 32 42
200901191507200 19-OCA-09 42 30
200901191507345 19-OCA-09 30 15
200901191509347 19-OCA-09 15 14
200902261503189 26-ŞUB-09 14 20
200902261506519 26-ŞUB-09 20 10
200902261508282 26-ŞUB-09 10 16
200903031534449 03-MAR-09 16 12
200903031534721 03-MAR-09 12 35
200903031534950 03-MAR-09 35
***************************************************************************
KEEP FIRST/LAST -> DENSE_RANK ile sıralanmış satırların FIRST varsa ilk, LAST varsa son satırı alınır, MAX yerine MIN,SUM,AVG yazılabilir
2. sorguda görüldüğü gibi 20090119 için first değer 15 last deger 42 dür.
select IDX, TARIH, TUTAR, MAX(TUTAR) KEEP (DENSE_RANK FIRST ORDER BY TUTAR ) OVER (PARTITION BY TARIH) KF,
MAX(TUTAR) KEEP (DENSE_RANK LAST ORDER BY TUTAR ) OVER (PARTITION BY TARIH) KL from ttest
IDX TARIH TUTAR KF KL
–
200901191509347 19-OCA-09 15 15 42
200901191507345 19-OCA-09 30 15 42
200901191505633 19-OCA-09 32 15 42
200901191507200 19-OCA-09 42 15 42
200902261506519 26-ŞUB-09 20 10 20
200902261503189 26-ŞUB-09 14 10 20
200902261508282 26-ŞUB-09 10 10 20
200903031534721 03-MAR-09 12 12 35
200903031534449 03-MAR-09 16 12 35
200903031534950 03-MAR-09 35 12 35
select IDX, TARIH, TUTAR, DENSE_RANK() OVER(PARTITION BY TARIH ORDER BY TUTAR ) NUM from ttest;
IDX TARIH TUTAR NUM
–
200901191509347 19-OCA-09 15 1
200901191507345 19-OCA-09 30 2
200901191505633 19-OCA-09 32 3
200901191507200 19-OCA-09 42 4
200902261508282 26-ŞUB-09 10 1
200902261503189 26-ŞUB-09 14 2
200902261506519 26-ŞUB-09 20 3
200903031534721 03-MAR-09 12 1
200903031534449 03-MAR-09 16 2
200903031534950 03-MAR-09 35 3
Bu şekilde de aynı sonuca ulaşabiliriz
select IDX, TARIH, TUTAR, MAX(TUTAR) OVER (PARTITION BY TARIH) Mn, MIN(TUTAR) OVER (PARTITION BY TARIH) MX from ttest;
***************************************************************************
CUME_DIST satırdaki değerin diğer satırlardaki değere göre pozisyonunu verir, belirtilen_degere_esit_veya_daha_kucuk_degerlerin_sayisi / belirtilenbolumdeki_toplam_kayit_sayisi
mesela 3. satıra bakalım. 20090119’a uygun 4 satır var. konum olarak 3. sırada 3/4 = .75
select IDX, TARIH, TUTAR, CUME_DIST() OVER (PARTITION BY TARIH ORDER BY TUTAR NULLS LAST) ORAN from ttest;
IDX TARIH TUTAR ORAN
–
200901191509347 19-OCA-09 15 .25
200901191507345 19-OCA-09 30 .5
200901191505633 19-OCA-09 32 .75
200901191507200 19-OCA-09 42 1
200902261508282 26-ŞUB-09 10 .333333333
200902261503189 26-ŞUB-09 14 .666666667
200902261506519 26-ŞUB-09 20 1
200903031534721 03-MAR-09 12 .333333333
200903031534449 03-MAR-09 16 .666666667
200903031534950 03-MAR-09 35 1
***************************************************************************
PERCENT_RANK satırdaki degerin diğer satırlardaki değere göre konumunun yuzde degeri, CUME_DIST’a benzer
mesle 3. satıra bakalım. (konumu-1)/(satir_satisi-1) 20090119’a uygun 4 satır var. konum olarak 3. sırada (3-1)/(4-1) = 2/3 = .666666667
select IDX, TARIH, TUTAR, PERCENT_RANK() OVER (PARTITION BY TARIH ORDER BY TUTAR NULLS LAST) ORAN from ttest;
IDX TARIH TUTAR ORAN
–
200901191509347 19-OCA-09 15 0
200901191507345 19-OCA-09 30 .333333333
200901191505633 19-OCA-09 32 .666666667
200901191507200 19-OCA-09 42 1
200902261508282 26-ŞUB-09 10 0
200902261503189 26-ŞUB-09 14 .5
200902261506519 26-ŞUB-09 20 1
200903031534721 03-MAR-09 12 0
200903031534449 03-MAR-09 16 .5
200903031534950 03-MAR-09 35 1
***************************************************************************
PERCENTILE_DISC = CUME_DIST fonksiyonunun verdigi degere esit veya buyuk ilk degeri almaya calisir. mesela ornekte 0.6ya esit veya buyuk ilk deger 1. sorguda gozuktugu gibi 20dir
PERCENTILE_CONT = Verilen yüzdelik değere göre ara değer üretir. formulü vardır. 0.6 yüzdelik değerine göre hesaplama yapalım
PERCENTILE_CONT(X) = ( eger (CRN = FRN = RN) ise (RN satirindaki deger) degilse (CRN – RN) ) * (FRN satirindaki deger ) + (RN -FRN) * (CRN satirindaki deger).
RN= (1+x*(n-1))= 1+0.6*(10-1) = 6.4
CRN = ceil(RN) = 7
FRN = FLOOR(RN) = 6
PERCENTILE_CONT(0.6) = (7-6.4)*20 + (6.4-6) * 30 = 24
select IDX, TARIH, TUTAR, CUME_DIST() OVER (ORDER BY TUTAR) CDist from ttest order by TUTAR;
IDX TARIH TUTAR CDIST
–
200902261508282 26-ŞUB-09 10 .1
200903031534721 03-MAR-09 12 .2
200902261503189 26-ŞUB-09 14 .3
200901191509347 19-OCA-09 15 .4
200903031534449 03-MAR-09 16 .5
200902261506519 26-ŞUB-09 20 .6
200901191507345 19-OCA-09 30 .7
200901191505633 19-OCA-09 32 .8
200903031534950 03-MAR-09 35 .9
200901191507200 19-OCA-09 42 1
SELECT PERCENTILE_DISC(0.6) WITHIN GROUP (ORDER BY TUTAR) AS perc_disc,
PERCENTILE_CONT(0.6) WITHIN GROUP (ORDER BY TUTAR) AS perc_cont
FROM ttest;
PERC_DISC PERC_CONT
24
***************************************************************************
Yaklasik degerlerin bulunmasi
ornekte gozuktugu uzere 23 tutarin yaklasik rank degeri 5dir. yani yaklasik olarak 5.siradadir
SELECT RANK (23) WITHIN GROUP (ORDER BY TUTAR DESC) AS hrank, yaklasik olarak 23, 5.sirada
PERCENT_RANK (23) WITHIN GROUP (ORDER BY TUTAR) AS hperc_rank, yaklasik olarak 23’un yuzdelik degeri 0.6
CUME_DIST (23) WITHIN GROUP (ORDER BY TUTAR) AS hcume_dist yaklasik olarak 23’un cum_dist degeri 0.6363
FROM ttest;
HRANK HPERC_RANK HCUME_DIST
.6 .636363636
select * from ttest t order by tutar desc;
IDX AD TUTAR S TARIH
– –
200901191507200 AHM 42 W 19-OCA-09
200903031534950 KEM 35 N 03-MAR-09
200901191505633 SAL 32 19-OCA-09
200901191507345 ONU 30 N 19-OCA-09
200902261506519 AAT 20 N 26-ŞUB-09
200903031534449 CAN 16 N 03-MAR-09
200901191509347 PET 15 N 19-OCA-09
200902261503189 SAD 14 W 26-ŞUB-09
200903031534721 ERM 12 N 03-MAR-09
200902261508282 SUL 10 N 26-ŞUB-09
************************************************************************
WIDTH_BUCKET, belirtilen aralıkta belirtilen kayıt kümesini degere uygun olarak parçalara ayırır
ornekte gozuktugu gibi, 0 ve 50 bizim min ve max araligimiz, buradaki degerleri 10 parcaya bolcez
42 max!a yakin yani 9 degeri almis, 20 ortalarda oldugu icin 5, 10 3 almis. 10 dan daha kucuk degerler olsaydı onlar da 1 ve 2 alacakti
WIDTH_BUCKET(alan, dusukdeger, yuksekdeger, parca_sayisi)
SELECT TUTAR,
WIDTH_BUCKET(TUTAR,0,50,10) AS WB_UP,
WIDTH_BUCKET(TUTAR,50, 0, 10) AS WB_DOWN
FROM ttest order by tutar desc;
TUTAR WB_UP WB_DOWN
42 9 2
35 8 4
32 7 4
30 7 5
20 5 7
16 4 7
15 4 8
14 3 8
12 3 8
10 3 9
***************************************************************************
FIRST_VALUE / LAST_VALUE kayit kumesindeki ilk degeri / son degeri verir.
ornekte goruldugu uzere, tarih’e gore kayit kumelerinde ilk kayiti ve son kayitin degerini almis. ilk kume icin ild deger 15 son deger 42 dir.
ornekte order by da kullanilabilirdi. FIRST_VALUE(TUTAR) OVER (PARTITION BY TARIH ORDER BY TUTAR) FV gibi yani. Fakat o zaman son satir o anki satir olarak goze alinirdi.
SELECT IDX, TARIH, TUTAR,
FIRST_VALUE(TUTAR) OVER (PARTITION BY TARIH) FV,
LAST_VALUE(TUTAR) OVER (PARTITION BY TARIH) LV
FROM ttest;
IDX TARIH TUTAR FV LV
–
200901191509347 19-OCA-09 15 15 42
200901191507345 19-OCA-09 30 15 42
200901191505633 19-OCA-09 32 15 42
200901191507200 19-OCA-09 42 15 42
200902261506519 26-ŞUB-09 20 20 10
200902261503189 26-ŞUB-09 14 20 10
200902261508282 26-ŞUB-09 10 20 10
200903031534721 03-MAR-09 12 12 35
200903031534449 03-MAR-09 16 12 35
200903031534950 03-MAR-09 35 12 35
***************************************************************************
bazen belirli sayide satir uretmek isteriz. kayit iceren bi tabloya ihtiyac vardir. kucuk bi tablo alsam da icinden gereksiz bilgi alsam deriz.
bu extra bilgi ama lazım olabilir. dual ve CONNECT BY ile bunu halledebiliriz.
SELECT trim(to_char(rownum-1,’00’)) SAAT FROM dual CONNECT BY LEVEL <= 5;
SAAT
–
00
01
02
03
04
incelenebilir : http://download.oracle.com/docs/cd/E11882_01/server.112/e10810/analysis.htm