Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Cara menggunakan fungsi Analitik di oracle (Over Partition by Keyword)

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengapa saya sepertinya tidak bisa memaksa Oracle 11g untuk mengkonsumsi lebih banyak CPU untuk satu kueri SQL?

  2. Oracle SQL - Jumlahkan dan kelompokkan data berdasarkan minggu

  3. Kunci database oracle sebelum menjalankan skrip Hapus/Muat data

  4. Daftar Elemen Format Datetime di Oracle

  5. Keamanan Database Oracle – Enkripsi dan Dekripsi