Posting ini adalah bagian dari tutorial Oracle SQL dan kami akan membahas fungsi Analytic di oracle (Over by partition) dengan contoh, penjelasan rinci.
Kita telah mempelajari tentang fungsi Oracle Aggregate seperti avg ,sum ,count. Mari kita ambil contoh
Pertama mari kita buat data sampelnya
CREATE TABLE "DEPT" ( "DEPTNO" NUMBER(2,0), "DNAME" VARCHAR2(14), "LOC" VARCHAR2(13), CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO") ) CREATE TABLE "EMP" ( "EMPNO" NUMBER(4,0), "ENAME" VARCHAR2(10), "JOB" VARCHAR2(9), "MGR" NUMBER(4,0), "HIREDATE" DATE, "SAL" NUMBER(7,2), "COMM" NUMBER(7,2), "DEPTNO" NUMBER(2,0), CONSTRAINT "PK_EMP" PRIMARY KEY ("EMPNO"), CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ENABLE ); SQL> desc emp Name Null? Type ---- ---- ----- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2) SQL> desc dept Name Null? Type ---- ----- ---- DEPTNO NOT NULL NUMBER(2) DNAME VARCHAR2(14) LOC VARCHAR2(13) insert into DEPT values(10, 'ACCOUNTING', 'NEW YORK'); insert into dept values(20, 'RESEARCH', 'DALLAS'); insert into dept values(30, 'RESEARCH', 'DELHI'); insert into dept values(40, 'RESEARCH', 'MUMBAI'); commit; insert into emp values( 7839, 'Allen', 'MANAGER', 7839, to_date('17-11-1981','dd-mm-yyyy'), 20, null, 10 ); insert into emp values( 7782, 'CLARK', 'MANAGER', 7839, to_date('9-06-1981','dd-mm-yyyy'), 0, null, 10 ); insert into emp values( 7934, 'MILLER', 'MANAGER', 7839, to_date('23-01-1982','dd-mm-yyyy'), 0, null, 10 ); insert into emp values( 7788, 'SMITH', 'ANALYST', 7788, to_date('17-12-1980','dd-mm-yyyy'), 800, null, 20 ); insert into emp values( 7902, 'ADAM, 'ANALYST', 7832, to_date('23-05-1987','dd-mm-yyyy'), 1100, null, 20 ); insert into emp values( 7876, 'FORD', 'ANALYST', 7566, to_date('3-12-1981','dd-mm-yyyy'), 3000, null, 20 ); insert into emp values( 7369, 'SCOTT', 'ANALYST', 7566, to_date('19-04-1987','dd-mm-yyyy'), 3000, null, 20 ); insert into emp values( 7698, 'JAMES', 'ANALYST', 7788, to_date('03-12-1981','dd-mm-yyyy'), 950, null, 30 ); insert into emp values( 7499, 'MARTIN', 'ANALYST', 7698, to_date('28-09-1981','dd-mm-yyyy'), 1250, null, 30 ); insert into emp values( 7844, 'WARD', 'ANALYST', 7698, to_date('22-02-1981','dd-mm-yyyy'), 1250, null, 30 ); insert into emp values( 7654, 'TURNER', 'ANALYST', 7698, to_date('08-09-1981','dd-mm-yyyy'), 1500, null, 30 ); insert into emp values( 7521, 'ALLEN', 'ANALYST', 7698, to_date('20-02-1981','dd-mm-yyyy'), 1600, null, 30 ); insert into emp values( 7900, 'BLAKE', 'ANALYST', 77698, to_date('01-05-1981','dd-mm-yyyy'), 2850, null, 30 ); commit;
Sekarang contoh fungsi agregat akan diberikan seperti di bawah ini
select count(*) from EMP; --------- 13 select sum (bytes) from dba_segments where tablespace_name='TOOLS'; ----- 100 SQL> select deptno ,count(*) from emp group by deptno; DEPTNO COUNT(*) ---------- ---------- 30 6 20 4 10 3
Di sini kita dapat melihat bahwa itu mengurangi jumlah baris di setiap kueri. Sekarang muncul pertanyaan apa yang harus dilakukan jika kita perlu mengembalikan semua baris dengan count(*) juga
Untuk itu oracle telah menyediakan seperangkat fungsi analitik. Jadi untuk menyelesaikan masalah terakhir , kita dapat menulis sebagai
select empno ,deptno , count(*) over (partition by deptno) from emp group by deptno;
Di sini count(*) over (partition by dept_no) adalah versi analitis dari fungsi count agregat. Pekerjaan kunci utama yang berbeda dengan fungsi agregat adalah over partisi oleh
Fungsi analitik menghitung nilai agregat berdasarkan sekelompok baris. Mereka berbeda dari fungsi agregat karena mereka mengembalikan beberapa baris untuk setiap grup. Kelompok baris disebut jendela dan didefinisikan oleh analytic_clause.
Berikut adalah sintaks umum
analytic_function([ arguments ]) OVER ([ query_partition_clause ] [ order_by_clause [ windowing_clause ] ])
Contoh
count(*) over (partition by deptno) avg(Sal) over (partition by deptno)
Mari kita bahas setiap bagian
query_partition_clause
Ini mendefinisikan grup baris. Bisa seperti di bawah
partisi menurut deptno :kumpulan baris dari deptno yang sama
atau
() :Semua baris
SQL> select empno ,deptno , count(*) over () from emp;
[ order_by_clause [ windowing_clause ] ]
Klausa ini digunakan ketika Anda ingin mengurutkan baris dalam partisi. Ini sangat berguna jika Anda ingin fungsi analitik mempertimbangkan urutan baris.
Contohnya adalah fungsi row_number
SQL> select deptno, ename, sal, row_number() over (partition by deptno order by sal) "row_number" from emp;
Contoh lainnya adalah
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE) running_sum from emp;
Windowing_clause
Ini selalu digunakan dengan klausa urutan demi dan memberikan kontrol lebih besar atas kumpulan baris dalam grup
Dengan klausa Windowing, Untuk setiap baris, jendela geser baris didefinisikan. Jendela menentukan rentang baris yang digunakan untuk melakukan perhitungan untuk baris saat ini. Ukuran jendela dapat didasarkan pada jumlah baris fisik atau interval logis seperti waktu.
Saat menggunakan urutan demi klausa dan tidak ada yang diberikan untuk windowing_clause, di bawah nilai default windowing_clause diambil
RANGE BETWEEN UNBOUNDED PRECEDING DAN CURRENT ROW atau RANGE UNBOUNDED PRECEDING
Artinya “Baris saat ini dan sebelumnya di saat ini partisi adalah baris yang harus digunakan dalam perhitungan”
Contoh di bawah ini dengan jelas menyatakan hal ini. Ini berjalan rata-rata di departemen
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE) running_sum from emp;
Sekarang windowing_clause dapat didefinisikan dengan beberapa cara
Mari kita pahami dulu terminologinya
BARIS menentukan jendela dalam unit fisik (baris).
RANGE menentukan jendela sebagai offset logis. klausa windowing RANGE hanya dapat digunakan dengan klausa ORDER BY yang berisi kolom atau ekspresi tipe data numerik atau tanggal
PRECEDING – dapatkan baris sebelum baris saat ini.
IKUTI – dapatkan baris setelah yang sekarang.
TIDAK TERBATAS – ketika digunakan dengan PRECEDING atau FOLLOWING, ia mengembalikan semua sebelum atau sesudah. BARIS SAAT INI
Jadi secara umum didefinisikan sebagai
BARIS SEBELUMNYA TANPA BATAS :Baris saat ini dan sebelumnya di partisi saat ini adalah baris yang harus digunakan dalam perhitungan
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE ROWS UNBOUNDED PRECEDING) running_sum from emp;
JANGKAUAN SEBELUMNYA TANPA BATAS :Baris saat ini dan sebelumnya di partisi saat ini adalah baris yang harus digunakan dalam perhitungan. Juga karena rentang ditentukan, semuanya membutuhkan nilai-nilai yang sama dengan baris saat ini.
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE RANGE UNBOUNDED PRECEDING) running_sum from emp;
Anda mungkin tidak melihat perbedaan antara rentang dan baris karena tanggal_pekerjaan berbeda untuk semua. Perbedaan akan menjadi lebih jelas jika kita menggunakan sal as order by klausa
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by sal RANGE UNBOUNDED PRECEDING) running_sum from emp;
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by sal ROWS UNBOUNDED PRECEDING) running_sum from emp;
Anda dapat menemukan perbedaannya di baris 6
RANGE value_expr SEBELUMNYA :Jendela dimulai dengan baris yang nilai ORDER BY-nya adalah baris ekspresi numerik yang kurang dari, atau sebelumnya, baris saat ini dan diakhiri dengan baris saat ini yang sedang diproses.
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE RANGE 365 PRECEDING) running_sum from emp;
Di sini dibutuhkan semua baris di mana nilai sewaan berada dalam 365 hari sebelum nilai sewaan dari baris saat ini
ROWS value_expr SEBELUMNYA :Jendela dimulai dengan baris yang diberikan dan diakhiri dengan baris saat ini yang sedang diproses
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE ROWS 2 PRECEDING) running_sum from emp;
Di sini jendela dimulai dari 2 baris sebelum baris saat ini
RANGE ANTARA ROW SAAT INI dan value_expr BERIKUT :Jendela dimulai dengan baris saat ini dan diakhiri dengan baris yang nilai ORDER BY-nya adalah baris ekspresi numerik kurang dari, atau mengikuti
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE ROWS between current row and 1 FOLLOWING) running_sum from emp;
BARIS ANTARA BARIS SAAT INI dan value_expr BERIKUT :Jendela dimulai dengan baris saat ini dan diakhiri dengan baris setelah baris saat ini
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE ROWS between current row and 1 FOLLOWING) running_sum from emp;
JANGKAUAN ANTARA PEMBELAJARAN TANPA BATAS dan PENGIKUTAN YANG TIDAK TERBATAS
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE RANGE BETWEEN UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING ) running_sum from emp;
RANGE ANTARA value_expr SEBELUMNYA dan value_expr MENGIKUTI
SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE RANGE BETWEEN 365 PRECEDING and 365 FOLLOWING ) running_sum from emp; 2 DEPTNO ENAME HIREDATE SAL RUNNING_SUM ---------- ---------- --------------- ---------- ----------- 10 CLARK 09-JUN-81 0 0 10 ALLEN 17-NOV-81 0 0 10 MILLER 23-JAN-82 0 0 20 SMITH 17-DEC-80 800 3800 20 FORD 03-DEC-81 3000 3800 20 SCOTT 19-APR-87 3000 4100 20 ADAMS 23-MAY-87 1100 4100 30 ALLEN 20-FEB-81 1600 9400 30 WARD 22-FEB-81 1250 9400 30 BLAKE 01-MAY-81 2850 9400 30 TURNER 08-SEP-81 1500 9400 30 MARTIN 28-SEP-81 1250 9400 30 JAMES 03-DEC-81 950 9400 13 rows selected.
Beberapa Catatan Penting
(1)Fungsi analitik adalah rangkaian operasi terakhir yang dilakukan dalam kueri kecuali untuk klausa ORDER BY akhir. Semua gabungan dan semua klausa WHERE, GROUP BY, dan HAVING diselesaikan sebelum fungsi analitik diproses. Oleh karena itu, fungsi analitik hanya dapat muncul di daftar pilih atau klausa ORDER BY.
(2)Fungsi analitik biasanya digunakan untuk menghitung agregat kumulatif, bergerak, terpusat, dan pelaporan.
Saya harap Anda menyukai penjelasan terperinci tentang fungsi Analytic di Oracle (di atas Partition Clause)
Artikel Terkait
Fungsi LEAD di Oracle
Fungsi DENSE di Oracle
Fungsi Oracle LISTAGG
Menggabungkan Data Menggunakan Fungsi Grup
https://docs.Oracle.com/cd/E11882_01/ server.112/e41084/functions004.htm