PostgreSQLOracle相容性-Analysis函式之keep
標籤
PostgreSQL , Oracle , 分析函式 , 視窗函式 , keep
背景
Oracle 分析函式KEEP,類似OVER的語法結構(當然,含義與之不同)。keep可以用於普通的查詢,也可以用於分組聚合,同時亦可用於視窗中。
SELECT deptno, MIN(t.mgr) KEEP (DENSE_RANK FIRST ORDER BY t.sal) a
from emp t
group by deptno;
以上a欄位,含義:
1、按deptno分組,
2、分組內按sal排序,
3、DENSE_RANK FIRST表示HOLD住sal排在前面的一組資料(當排在前面的sal有重複值時,多條被HOLD),
4、然後在這組記錄中,執行前面的聚合函式,這裡是min(t.mgr)。
例子
create table emp (empno int, ename varchar2(64), mgr int, sal int, deptno int);
insert into emp values (7369, `SMITH`, 7902, 800, 20);
insert into emp values (7900, `JAMES`, 7698, 950, 30);
insert into emp values (7876, `ADAMS`, 7788 , 1100, 20);
insert into emp values (7521, `WARD` , 7698 , 1250, 30);
insert into emp values (7654, `MARTIN`, 7698 , 1250, 30);
insert into emp values (7934, `MILLER`, 7782 , 1300, 10);
insert into emp values (7844, `TURNER`, 7698 , 1500, 30);
insert into emp values (7499, `ALLEN`, 7698, 1600, 30);
insert into emp values (7782, `CLARK`, 7839 , 2450, 10);
insert into emp values (7698, `BLAKE`, 7839 , 2850, 30);
insert into emp values (7566, `JONES`, 7839 , 2975, 20);
insert into emp values (7788, `SCOTT`, 7566 , 3000, 20);
insert into emp values (7902, `FORD` , 7555 , 3000, 20);
insert into emp values (7839, `KING` , 7567, 5000, 10);
postgres=# select * from emp order by deptno,sal,mgr;
empno | ename | mgr | sal | deptno
-------+--------+------+------+--------
7934 | MILLER | 7782 | 1300 | 10
7782 | CLARK | 7839 | 2450 | 10
7839 | KING | 7567 | 5000 | 10
7369 | SMITH | 7902 | 800 | 20
7876 | ADAMS | 7788 | 1100 | 20
7566 | JONES | 7839 | 2975 | 20
7902 | FORD | 7555 | 3000 | 20
7788 | SCOTT | 7566 | 3000 | 20
7900 | JAMES | 7698 | 950 | 30
7654 | MARTIN | 7698 | 1250 | 30
7521 | WARD | 7698 | 1250 | 30
7844 | TURNER | 7698 | 1500 | 30
7499 | ALLEN | 7698 | 1600 | 30
7698 | BLAKE | 7839 | 2850 | 30
(14 rows)
Oracle 查詢如下,下面看看PostgreSQL的相容寫法
SELECT
deptno,
MIN(t.mgr) KEEP(DENSE_RANK FIRST ORDER BY t.sal) a, -- FIRST對應 pg order by sal , dense_rank()=1
MAX(t.mgr) KEEP(DENSE_RANK FIRST ORDER BY t.sal) b,
MIN(t.mgr) KEEP(DENSE_RANK LAST ORDER BY t.sal) c, -- LAST對應 pg order by sal desc , dense_rank()=1
MAX(t.mgr) KEEP(DENSE_RANK LAST ORDER BY t.sal) d
FROM emp t group by deptno;
DEPTNO A B C D
---------- ---------- ---------- ---------- ----------
10 7782 7782 7567 7567
20 7902 7902 7555 7566
30 7698 7698 7839 7839
PostgreSQL keep 相容用法
1、建表
create table emp (empno int, ename text, mgr int, sal int, deptno int);
2、灌入資料
insert into emp values (7369, `SMITH`, 7902, 800, 20);
insert into emp values (7900, `JAMES`, 7698, 950, 30);
insert into emp values (7876, `ADAMS`, 7788 , 1100, 20);
insert into emp values (7521, `WARD` , 7698 , 1250, 30);
insert into emp values (7654, `MARTIN`, 7698 , 1250, 30);
insert into emp values (7934, `MILLER`, 7782 , 1300, 10);
insert into emp values (7844, `TURNER`, 7698 , 1500, 30);
insert into emp values (7499, `ALLEN`, 7698, 1600, 30);
insert into emp values (7782, `CLARK`, 7839 , 2450, 10);
insert into emp values (7698, `BLAKE`, 7839 , 2850, 30);
insert into emp values (7566, `JONES`, 7839 , 2975, 20);
insert into emp values (7788, `SCOTT`, 7566 , 3000, 20);
insert into emp values (7902, `FORD` , 7555 , 3000, 20);
insert into emp values (7839, `KING` , 7567, 5000, 10);
3、分開查詢如下
postgres=# select deptno,min(mgr),max(mgr) from (
select *, dense_rank() over w1 from emp window w1 as (partition by deptno order by sal) -- 得到dense_rank的值 , order by sal 對應 FIRST
) t
where dense_rank=1
group by deptno;
deptno | min | max
--------+------+------
10 | 7782 | 7782
20 | 7902 | 7902
30 | 7698 | 7698
(3 rows)
postgres=# select deptno,min(mgr),max(mgr) from (
select *, dense_rank() over w1 from emp window w1 as (partition by deptno order by sal desc) -- 得到dense_rank的值 , order by sal desc 對應 LAST
) t
where dense_rank=1
group by deptno;
deptno | min | max
--------+------+------
10 | 7567 | 7567
20 | 7555 | 7566
30 | 7839 | 7839
(3 rows)
4、合併查詢,用JOIN
select t1.deptno, t1.min, t1.max, t2.min, t2.max from
(select deptno,min(mgr),max(mgr) from (select *, dense_rank() over w1 from emp window w1 as (partition by deptno order by sal)) t where dense_rank=1 group by deptno) t1
join
(select deptno,min(mgr),max(mgr) from (select *, dense_rank() over w1 from emp window w1 as (partition by deptno order by sal desc)) t where dense_rank=1 group by deptno) t2
using (deptno);
deptno | min | max | min | max
--------+------+------+------+------
10 | 7782 | 7782 | 7567 | 7567
20 | 7902 | 7902 | 7555 | 7566
30 | 7698 | 7698 | 7839 | 7839
(3 rows)
參考
https://docs.oracle.com/cd/B28359_01/server.111/b28313/analysis.htm
https://blog.csdn.net/java3344520/article/details/5603309
https://oracle-base.com/articles/misc/rank-dense-rank-first-last-analytic-functions
https://stackoverflow.com/questions/10756717/sql-server-how-to-imitate-oracle-keep-dense-rank-query
https://www.postgresql.org/docs/10/static/functions-window.html
《PostgreSQL SELECT 的高階用法(CTE, LATERAL, ORDINALITY, WINDOW, SKIP LOCKED, DISTINCT, GROUPING SETS, …)》
相關文章
- PostgreSQLOracle相容性之NUMTODSINTERVALSQLOracle
- PostgreSQLOracle相容性之-roundintervalSQLOracle
- PostgreSQLOracle相容性之-PL/SQLDETERMINISTIC與PG函式穩定性(immutable,stable,volatile)SQLOracle函式
- PostgreSQLOracle相容性-synonym匿名SQLOracle
- PostgreSQLOracle相容性之-全域性臨時表globaltemptableSQLOracle
- PostgreSQLOracle相容性之-PartitionByOuterJoin實現稠化報表SQLOracle
- PostgreSQLOracle相容性-connectby2SQLOracle
- 分析函式中的KEEP函式
- PostgreSQLOracle相容性-substrb-orafcesubstrb適配OraclesubstrbSQLOracle
- PostgreSQLOracle相容性之-系統列(ctid,oid,cmin,cmax,xmin,xmax)SQLOracle
- oracle分析函式,keep and over解說Oracle函式
- PostgreSQLOraclePL/SQL相容性之-AGGREGATEUSINGClause聚合函式SQLOracleGC函式
- 分析函式——keep(dense_rank first/last)函式AST
- SQL KEEP 視窗函式等價改寫案例SQL函式
- Oracle vs PostgreSQL Develop(14) - 分析函式KEEP DENSE_RANKOracleSQLdev函式
- 字串函式之Strtok()函式字串函式
- PostgreSQLoracle相容性-字串內嵌NULL字元(空字元)chr(0)轉換為chr(32)SQLOracle字串Null字元
- PostgreSQLOracle相容性之-connectby高階選項CONNECT_BY_ISLEAF、SYS_CONNECT_BY_PATH、CONNECT_BY_ISCYCLE、LEVELSQLOracle
- Python 擴充之特殊函式(lambda 函式,map 函式,filter 函式,reduce 函式)Python函式Filter
- 常見函式之單行函式函式
- 【Analytic】分析函式之MIN函式函式
- 【Analytic】分析函式之MAX函式函式
- 【Analytic】分析函式之AVG函式函式
- 【Analytic】分析函式之RANK函式函式
- 【Analytic】分析函式之COUNT函式函式
- Kotlin之“with”函式和“apply”函式Kotlin函式APP
- ORACLE單行函式與多行函式之七:多行函式之分組函式示例Oracle函式
- ORACLE單行函式與多行函式之四:日期函式示例Oracle函式
- ORACLE單行函式與多行函式之六:通用函式示例Oracle函式
- javascript函式之——splitJavaScript函式
- Oracle之函式索引Oracle函式索引
- 函式之遞迴函式遞迴
- PHP函式漏洞審計之addslashes函式-PHP函式
- 函式的祕密之 函式返回值函式
- 【Spark篇】---SparkSql之UDF函式和UDAF函式SparkSQL函式
- 【Analytic】分析函式之ROW_NUMBER函式函式
- 【Analytic】分析函式之DENSE_RANK函式函式
- 【Analytic】分析函式之FIRST_VALUE函式函式