sql >> Databáze >  >> RDS >> Oracle

Jak používat analytické funkce v oracle (přes rozdělení podle klíčového slova)

Tento příspěvek je součástí tutoriálu Oracle SQL a budeme diskutovat o analytických funkcích v oracle (přes oddíl) s příklady a podrobným vysvětlením.

Už jsme studovali funkci Oracle Aggregate jako avg, sum, count. Vezměme si příklad

Nejprve vytvoříme ukázková data

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;

Nyní bude uveden příklad agregačních funkcí, jak je uvedeno níže

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

Zde vidíme, že snižuje počet řádků v každém z dotazů. Nyní přichází otázka, co dělat, pokud potřebujeme vrátit všechny řádky s count(*) také

Pro toto orákulum poskytlo sadu analytických funkcí. Abychom vyřešili poslední problém , můžeme napsat jako

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

Zde count(*) over (partition by dept_no) je analytická verze funkce count agregace. Hlavní klíčová práce, která se liší agregační funkcí, je přes rozdělení podle

Analytické funkce počítají agregovanou hodnotu na základě skupiny řádků. Od agregačních funkcí se liší tím, že vracejí více řádků pro každou skupinu. Skupina řádků se nazývá okno a je definována klauzulí analytic_clause.

Zde je obecná syntaxe

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

Příklad

count(*) over (partition by deptno)

avg(Sal) over (partition by deptno)

Pojďme si projít každou část

klauzule_dotazu
Definovala skupinu řádků. Může se to líbit níže

rozdělení podle oddělení :skupina řádků stejného oddělení
nebo
() :Všechny řádky

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

[ order_by_clause [ windowing_clause ] ]

Tato klauzule se používá, když chcete seřadit řádky v oddílu. To je zvláště užitečné, pokud chcete, aby analytická funkce zvážila pořadí řádků.

Příkladem bude funkce číslo_řádku

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

Dalším příkladem by bylo

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

Windowing_clause

To se vždy používá s klauzulí podle pořadí a poskytuje větší kontrolu nad sadou řádků ve skupině

S klauzulí Windowing je pro každý řádek definováno posuvné okno řádků. Okno určuje rozsah řádků použitých k provedení výpočtů pro aktuální řádek. Velikosti oken mohou být založeny buď na fyzickém počtu řádků, nebo na logickém intervalu, jako je čas.

Když použijete pořadí podle klauzule a pro windowing_clause není uvedeno nic, použije se pod výchozí hodnota windowing_clause
ROZSAH MEZI NEODPOVĚDNÝM PŘEDCHOZÍM A AKTUÁLNÍM ŘÁDKEM nebo ROZSAH NEODPOVĚDNÝ PŘEDCHOZÍM
To znamená „Aktuální a předchozí řádky v aktuálním oddíl jsou řádky, které by měly být použity při výpočtu”

Níže uvedený příklad to jasně říká. To odpovídá běžnému průměru v oddělení

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

Nyní lze windowing_clause definovat několika způsoby
Nejprve pochopíme terminologii

ŘÁDKY určuje okno ve fyzických jednotkách (řádcích).
RANGE určuje okno jako logický offset. klauzuli okna RANGE lze použít pouze s klauzulemi  ORDER BY obsahujícími sloupce nebo výrazy číselných nebo datových typů dat
PŘEDCHOZÍ – získat řádky před aktuálním.
NÁSLEDUJÍCÍ – získat řádky za aktuálním.
NEBOUZENO – při použití s ​​PRECEDING nebo FOLLOWING se vrátí vše před nebo za. AKTUÁLNÍ ŘÁDEK

Obecně se tedy definuje jako

PŘEDCHÁZEJÍCÍ ŘÁDY BEZ OMEZENÍ :Aktuální a předchozí řádky v aktuálním oddílu jsou řádky, které by měly být použity při výpočtu

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

PŘEDCHOZÍ NEOMEZENÝ ROZSAH :Aktuální a předchozí řádky v aktuálním oddílu jsou řádky, které by měly být použity při výpočtu. Vzhledem k tomu, že je zadán rozsah, vše nabývá hodnot, které se rovnají aktuálním řádkům.

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

Rozdíl mezi rozsahem a řádky možná neuvidíte, protože datum_nájmu se u všech liší. Rozdíl bude jasnější, když použijeme sal jako objednávku po klauzuli

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;

Rozdíl najdete na řádku 6

RANGE value_expr PŘEDCHOZÍ :Okno začíná řádkem, jehož hodnota ORDER BY je řádky číselného výrazu menší než nebo předcházející aktuálnímu řádku, a končí aktuálním zpracovávaným řádkem.

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

Zde se převezmou všechny řádky, ve kterých hodnota nájemného spadá do 365 dnů předcházejících hodnotě nájemného v aktuálním řádku

ROWS value_expr PŘEDCHOZÍ :Okno začíná daným řádkem a končí aktuálním zpracovávaným řádkem

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

Zde okno začíná od 2 řádků předcházejících aktuálnímu řádku

NÁSLEDUJÍCÍ ROZSAH MEZI AKTUÁLNÍM ŘÁDKEM a value_expr :Okno začíná aktuálním řádkem a končí řádkem, jehož hodnota ORDER BY je řádky číselného výrazu menší než nebo následující

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;

ŘÁDKY MEZI AKTUÁLNÍM ŘÁDKEM a NÁSLEDUJÍCÍ value_expr :Okno začíná aktuálním řádkem a končí řádky po aktuálním řádku

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;

ROZSAH MEZI NEOMEZENÝM PŘEDCHOZÍM A NEOMEZENÝM NÁSLEDUJÍCÍM

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;

ROZSAH MEZI value_expr PŘEDCHOZÍM a value_expr NÁSLEDUJÍCÍ

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.

Některé důležité poznámky
(1)Analytické funkce jsou poslední sadou operací prováděných v dotazu s výjimkou závěrečné klauzule ORDER BY. Všechna spojení a všechny klauzule WHERE, GROUP BY a HAVING jsou dokončeny před zpracováním analytických funkcí. Proto se analytické funkce mohou objevit pouze ve výběrovém seznamu nebo v klauzuli ORDER BY.
(2)Analytické funkce se běžně používají k výpočtu kumulativních, pohyblivých, centrovaných a vykazovacích agregátů.

Doufám, že se vám líbí toto podrobné vysvětlení analytických funkcí v oracle (over by Partition Clause)

Související články
Funkce LEAD v Oracle
Funkce DENSE v Oracle
Funkce Oracle LISTAGG
Agregace dat pomocí skupinových funkcí
https://docs.oracle.com/cd/E11882_01/ server.112/e41084/functions004.htm


  1. Jak se připojím k databázi MySQL v Pythonu?

  2. Jak volat uloženou proceduru MySQL v Pythonu

  3. Vraťte Unixové časové razítko v PostgreSQL

  4. Jak získat seznam sloupců s jedinečnými omezeními v databázi SQL Server - SQL Server / Výukový program TSQL, část 98