Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Cách sử dụng các hàm Phân tích trong oracle (Over Partition theo Keyword)

Bài đăng này là một phần của hướng dẫn Oracle SQL và chúng ta sẽ thảo luận về các hàm Phân tích trong oracle (Theo phân vùng) với các ví dụ, giải thích chi tiết.

Chúng ta đã nghiên cứu về hàm Aggregate của Oracle như avg, sum, count. Hãy lấy một ví dụ

Đầu tiên, hãy tạo dữ liệu mẫu

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;

Bây giờ, ví dụ về các hàm tổng hợp sẽ được đưa ra như dưới đây

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

Ở đây chúng ta có thể thấy rằng nó làm giảm số hàng trong mỗi truy vấn. Bây giờ câu hỏi đặt ra là phải làm gì nếu chúng ta cần trả về tất cả các hàng với số đếm (*)

Đối với điều đó tiên tri đã cung cấp một tập hợp các hàm phân tích. Vì vậy, để giải quyết vấn đề cuối cùng, chúng ta có thể viết là

select empno ,deptno , count(*) over (partition by deptno) from emp group by deptno;

Ở đây count (*) over (phân vùng theo dept_no) là phiên bản phân tích của hàm tổng hợp đếm. Công việc chính khác nhau theo chức năng tổng hợp là vượt quá phân vùng theo

Các hàm phân tích tính toán giá trị tổng hợp dựa trên một nhóm hàng. Chúng khác với các hàm tổng hợp ở chỗ chúng trả về nhiều hàng cho mỗi nhóm. Nhóm các hàng được gọi là cửa sổ và được xác định bởi analytic_clause.

Đây là cú pháp chung

analytic_function([ arguments ]) OVER ([ query_partition_clause ] [ order_by_clause [ windowing_clause ] ])

Ví dụ

count(*) over (partition by deptno)

avg(Sal) over (partition by deptno)

Hãy xem qua từng phần

query_partition_clause
Nó xác định nhóm hàng. Nó có thể như dưới đây

phân vùng theo deptno:nhóm các hàng của cùng một deptno
hoặc
():Tất cả các hàng

SQL> select empno ,deptno , count(*) over () from emp;

[order_by_clause [windowing_clause]]

Mệnh đề này được sử dụng khi bạn muốn sắp xếp các hàng trong phân vùng. Điều này đặc biệt hữu ích nếu bạn muốn chức năng phân tích xem xét thứ tự của các hàng.

Ví dụ sẽ là hàm row_number

SQL> select
deptno, ename, sal, 
 row_number() over (partition by deptno order by sal) "row_number" from emp;

Một ví dụ khác sẽ là

SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE) running_sum from emp;

Windowing_clause

Điều này luôn được sử dụng với mệnh đề theo thứ tự và cung cấp nhiều quyền kiểm soát hơn đối với tập hợp các hàng trong nhóm

Với mệnh đề Windowing, Đối với mỗi hàng, một cửa sổ trượt của các hàng được xác định. Cửa sổ xác định phạm vi hàng được sử dụng để thực hiện các phép tính cho hàng hiện tại. Kích thước cửa sổ có thể dựa trên số hàng vật lý hoặc khoảng thời gian hợp lý chẳng hạn như thời gian.

Khi sử dụng mệnh đề theo thứ tự và không có gì được cung cấp cho windowing_clause, giá trị mặc định dưới đây của windowing_clause sẽ được lấy
RANGE GIỮA ĐƯỜNG CHÍNH XÁC VÀ HIỆN TẠI hoặc RANGE UNBOUNDED PRECEDING
Nó có nghĩa là “Dòng hiện tại và hàng trước đó phân vùng là các hàng sẽ được sử dụng trong tính toán ”

Ví dụ dưới đây nói rõ điều này. Đây là mức trung bình hoạt động trong bộ phận

SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE) running_sum from emp;

Giờ đây, windowing_clause có thể được định nghĩa bằng một số cách
Trước tiên hãy hiểu thuật ngữ này

ROWS chỉ định cửa sổ theo đơn vị vật lý (hàng).
RANGE chỉ định cửa sổ như một độ lệch hợp lý. mệnh đề cửa sổ RANGE chỉ có thể được sử dụng với mệnh đề ORDER BY có chứa cột hoặc biểu thức của kiểu dữ liệu số hoặc ngày
PRECEDING - lấy các hàng trước hàng hiện tại.
THEO DÕI - lấy các hàng sau hàng hiện tại.
ĐÃ BỎ QUA - khi được sử dụng với PRECEDING hoặc F SAU, nó trả về tất cả trước hoặc sau. ROW HIỆN TẠI

Vì vậy, nó thường được định nghĩa là

ROWS UNBOUNDED PRECEDING :Các hàng hiện tại và trước đó trong phân vùng hiện tại là các hàng sẽ được sử dụng trong tính toán

SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE ROWS UNBOUNDED PRECEDING) running_sum from emp;

RANGE UNBOUNDED PRECEDING :Các hàng hiện tại và trước đó trong phân vùng hiện tại là các hàng sẽ được sử dụng trong tính toán. Ngoài ra, vì phạm vi được chỉ định, tất cả đều nhận các giá trị bằng với các hàng hiện tại.

SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE RANGE UNBOUNDED PRECEDING) running_sum from emp;

Bạn có thể không thấy sự khác biệt giữa phạm vi và các hàng vì ngày thuê là khác nhau cho tất cả. Sự khác biệt sẽ trở nên rõ ràng hơn nếu chúng ta sử dụng sal làm thứ tự theo mệnh đề

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;

Bạn có thể tìm thấy sự khác biệt ở dòng 6

RANGE value_expr PRECEDING :Cửa sổ bắt đầu với hàng có giá trị ORDER BY là các hàng biểu thức số nhỏ hơn hoặc đứng trước hàng hiện tại và kết thúc bằng hàng hiện tại đang được xử lý.

SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE RANGE 365 PRECEDING) running_sum from emp;

Ở đây, nó lấy tất cả các hàng trong đó giá trị thuê giảm trong vòng 365 ngày trước giá trị thuê của hàng hiện tại

ROWS value_expr PRECEDING :Cửa sổ bắt đầu với hàng đã cho và kết thúc với hàng hiện tại đang được xử lý

SQL> select deptno, ename,hiredate, sal,sum(sal) over (partition by deptno order by HIREDATE ROWS 2 PRECEDING) running_sum from emp;

Ở đây, cửa sổ bắt đầu từ 2 hàng trước hàng hiện tại

RANGE GIỮA ROW HIỆN TẠI và value_expr SAU ĐÂY :Cửa sổ bắt đầu bằng hàng hiện tại và kết thúc bằng hàng có giá trị ORDER BY là các hàng biểu thức số nhỏ hơn hoặc theo sau

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;

ROW GIỮA ROW HIỆN TẠI và value_expr SAU ĐÂY :Cửa sổ bắt đầu bằng hàng hiện tại và kết thúc bằng các hàng sau hàng hiện tại

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;

RANGE GIỮA KHI CHƯA ĐƯỢC CẬP NHẬT CHÍNH XÁC VÀ ĐOẠN SAU KHÔNG ĐƯỢC TỔ CHỨC

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 BETWEEN value_expr PRECEDING và value_expr THEO DÕI

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.

Một số lưu ý quan trọng
(1) Các hàm phân tích là tập hợp các thao tác cuối cùng được thực hiện trong một truy vấn ngoại trừ mệnh đề ORDER BY cuối cùng. Tất cả các phép nối và tất cả các mệnh đề WHERE, GROUP BY và HAVING được hoàn thành trước khi các hàm phân tích được xử lý. Do đó, các hàm phân tích chỉ có thể xuất hiện trong danh sách lựa chọn hoặc mệnh đề ORDER BY.
(2) Các hàm phân tích thường được sử dụng để tính toán các tổng hợp tích lũy, di chuyển, căn giữa và báo cáo.

Tôi hy vọng bạn thích phần giải thích chi tiết này về các hàm Phân tích trong oracle (theo Điều khoản phân vùng)

Các bài viết có liên quan
Hàm LEAD trong Oracle
Hàm DENSE trong Oracle
Hàm LISTAGG của Oracle
Tổng hợp dữ liệu bằng các hàm nhóm
https://docs.oracle.com/cd/E11882_01/ máy chủ.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. Oracle sang Excel - Quy trình xuất PL / SQL

  2. Cách tìm bảng nơi thống kê bị khóa

  3. Có cách nào, trong ORACLE, để nối nhiều dòng hàng thành một dòng duy nhất, sử dụng hai bảng, trong đó các giá trị cuối cùng được phân tách bằng dấu phẩy không?

  4. Làm thế nào để tìm được nhân viên có mức lương cao thứ hai?

  5. Tại sao tôi dường như không thể buộc Oracle 11g tiêu thụ nhiều CPU hơn cho một truy vấn SQL duy nhất