知识大全 OracleSQL精妙SQL语句讲解
Posted 语句
篇首语:天下无难事,只怕有心人。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 OracleSQL精妙SQL语句讲解相关的知识,希望对你有一定的参考价值。
OracleSQL精妙SQL语句讲解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
行列转换 行转列
DROP TABLE t_change_lc;
CREATE TABLE t_change_lc (card_code VARCHAR ( ) q NUMBER bal NUMBER);
INSERT INTO t_change_lc
SELECT card_code ROWNUM q trunc(dbms_random VALUE * ) bal FROM dual CONNECT BY ROWNUM <=
UNION
SELECT card_code ROWNUM q trunc(dbms_random VALUE * ) bal FROM dual CONNECT BY ROWNUM <= ;
SELECT * FROM t_change_lc;
SELECT a card_code
SUM(decode(a q a bal )) q
SUM(decode(a q a bal )) q
SUM(decode(a q a bal )) q
SUM(decode(a q a bal )) q
FROM t_change_lc a
GROUP BY a card_code
ORDER BY ;
行列转换 列转行
DROP TABLE t_change_cl;
CREATE TABLE t_change_cl AS
SELECT a card_code
SUM(decode(a q a bal )) q
SUM(decode(a q a bal )) q
SUM(decode(a q a bal )) q
SUM(decode(a q a bal )) q
FROM t_change_lc a
GROUP BY a card_code
ORDER BY ;
SELECT * FROM t_change_cl;
SELECT t card_code
t rn q
decode(t rn t q t q t q t q ) bal
FROM (SELECT a * b rn
FROM t_change_cl a
(SELECT ROWNUM rn FROM dual CONNECT BY ROWNUM <= ) b) t
ORDER BY ;
行列转换 行转列 合并
DROP TABLE t_change_lc_ma;
CREATE TABLE t_change_lc_ma AS SELECT card_code quarter_ ||q AS q FROM t_change_lc;
SELECT * FROM t_change_lc_ma;
SELECT t card_code substr(MAX(sys_connect_by_path(t q ; )) ) q
FROM (SELECT a card_code
a q
row_number() over(PARTITION BY a card_code ORDER BY a q) rn
FROM t_change_lc_ma a) t
START WITH t rn =
CONNECT BY t card_code = PRIOR t card_code
AND t rn = PRIOR t rn
GROUP BY t card_code;
行列转换 列转行 分割
DROP TABLE t_change_cl_ma;
CREATE TABLE t_change_cl_ma AS
SELECT t card_code substr(MAX(sys_connect_by_path(t q ; )) ) q
FROM (SELECT a card_code
a q
row_number() over(PARTITION BY a card_code ORDER BY a q) rn
FROM t_change_lc_ma a) t
START WITH t rn =
CONNECT BY t card_code = PRIOR t card_code
AND t rn = PRIOR t rn
GROUP BY t card_code;
SELECT * FROM t_change_cl_ma;
SELECT t card_code
substr(t q
instr( ; || t q ; rn)
instr(t q || ; ; rn) instr( ; || t q ; rn)) q
FROM (SELECT a card_code a q b rn
FROM t_change_cl_ma a
(SELECT ROWNUM rn FROM dual CONNECT BY ROWNUM <= ) b
WHERE instr( ; || a q ; rn) > ) t
ORDER BY ;
实现一条记录根据条件多表插入
DROP TABLE t_ia_src;
CREATE TABLE t_ia_src AS SELECT a ||ROWNUM c b ||ROWNUM c FROM dual CONNECT BY ROWNUM<= ;
DROP TABLE t_ia_dest_ ;
CREATE TABLE t_ia_dest_ (flag VARCHAR ( ) c VARCHAR ( ));
DROP TABLE t_ia_dest_ ;
CREATE TABLE t_ia_dest_ (flag VARCHAR ( ) c VARCHAR ( ));
DROP TABLE t_ia_dest_ ;
CREATE TABLE t_ia_dest_ (flag VARCHAR ( ) c VARCHAR ( ));
SELECT * FROM t_ia_src;
SELECT * FROM t_ia_dest_ ;
SELECT * FROM t_ia_dest_ ;
SELECT * FROM t_ia_dest_ ;
INSERT ALL
WHEN (c IN ( a a )) THEN
INTO t_ia_dest_ (flag c) VALUES(flag c )
WHEN (c IN ( a a )) THEN
INTO t_ia_dest_ (flag c) VALUES(flag c )
ELSE
INTO t_ia_dest_ (flag c) VALUES(flag ||flag c ||c )
SELECT c c f flag f flag FROM t_ia_src;
如果存在就更新 不存在就插入用一个语句实现
DROP TABLE t_mg;
CREATE TABLE t_mg(code VARCHAR ( ) NAME VARCHAR ( ));
SELECT * FROM t_mg;
MERGE INTO t_mg a
USING (SELECT the code code the name NAME FROM dual) b
ON (de = de)
WHEN MATCHED THEN
UPDATE SET a NAME = b NAME
WHEN NOT MATCHED THEN
INSERT (code NAME) VALUES (de b NAME);
抽取/删除重复记录
DROP TABLE t_dup;
CREATE TABLE t_dup AS SELECT code_ ||ROWNUM code dbms_random string( z ) NAME FROM dual CONNECT BY ROWNUM<= ;
INSERT INTO t_dup SELECT code_ ||ROWNUM code dbms_random string( z ) NAME FROM dual CONNECT BY ROWNUM<= ;
SELECT * FROM t_dup;
SELECT * FROM t_dup a WHERE a ROWID <> (SELECT MIN(b ROWID) FROM t_dup b WHERE de=de);
SELECT de b NAME
FROM (SELECT de
a NAME
row_number() over(PARTITION BY de ORDER BY a ROWID) rn
FROM t_dup a) b
WHERE b rn > ;
IN/EXISTS的不同适用环境
t_orders customer_id有索引
SELECT a *
FROM t_employees a
WHERE a employee_id IN
(SELECT b sales_rep_id FROM t_orders b WHERE b customer_id = );
SELECT a *
FROM t_employees a
WHERE EXISTS (SELECT
FROM t_orders b
WHERE b customer_id =
AND a employee_id = b sales_rep_id);
t_employees department_id有索引
SELECT a *
FROM t_employees a
WHERE a department_id =
AND EXISTS
(SELECT FROM t_orders b WHERE a employee_id = b sales_rep_id);
SELECT a *
FROM t_employees a
WHERE a department_id =
AND a employee_id IN (SELECT b sales_rep_id FROM t_orders b);
FBI
DROP TABLE t_fbi;
CREATE TABLE t_fbi AS
SELECT ROWNUM rn dbms_random STRING( z ) NAME SYSDATE + dbms_random VALUE * dt FROM dual
CONNECT BY ROWNUM <= ;
CREATE INDEX idx_nonfbi ON t_fbi(dt);
DROP INDEX idx_fbi_ ;
CREATE INDEX idx_fbi_ ON t_fbi(trunc(dt));
SELECT * FROM t_fbi WHERE trunc(dt) = to_date( yyyy mm dd ) ;
不建议使用
SELECT * FROM t_fbi WHERE to_char(dt yyyy mm dd ) = ;
LOOP中的MIT/ROLLBACK
DROP TABLE t_loop PURGE;
create TABLE t_loop AS SELECT * FROM user_objects WHERE = ;
SELECT * FROM t_loop;
逐行提交
DECLARE
BEGIN
FOR cur IN (SELECT * FROM user_objects) LOOP
INSERT INTO t_loop VALUES cur;
MIT;
END LOOP;
END;
模拟批量提交
DECLARE
v_count NUMBER;
BEGIN
FOR cur IN (SELECT * FROM user_objects) LOOP
INSERT INTO t_loop VALUES cur;
v_count := v_count + ;
IF v_count >= THEN
MIT;
END IF;
END LOOP;
MIT;
END;
真正的批量提交
DECLARE
CURSOR cur IS
SELECT * FROM user_objects;
TYPE rec IS TABLE OF user_objects%ROWTYPE;
recs rec;
BEGIN
OPEN cur;
WHILE (TRUE) LOOP
FETCH cur BULK COLLECT
INTO recs LIMIT ;
forall 实现批量
FORALL i IN recs COUNT
INSERT INTO t_loop VALUES recs (i);
MIT;
EXIT WHEN cur%NOTFOUND;
END LOOP;
CLOSE cur;
END;
悲观锁定/乐观锁定
DROP TABLE t_lock PURGE;
CREATE TABLE t_lock AS SELECT ID FROM dual;
SELECT * FROM t_lock;
常见的实现逻辑 隐含bug
DECLARE
v_cnt NUMBER;
BEGIN
这里有并发性的bug
SELECT MAX(ID) INTO v_cnt FROM t_lock;
here for other operation
v_cnt := v_cnt + ;
INSERT INTO t_lock (ID) VALUES (v_cnt);
MIT;
END;
高并发环境下 安全的实现逻辑
DECLARE
v_cnt NUMBER;
BEGIN
对指定的行取得lock
SELECT ID INTO v_cnt FROM t_lock WHERE ID= FOR UPDATE;
在有lock的情况下继续下面的操作
SELECT MAX(ID) INTO v_cnt FROM t_lock;
here for other operation
v_cnt := v_cnt + ;
INSERT INTO t_lock (ID) VALUES (v_cnt);
MIT; 提交并且释放lock
END;
硬解析/软解析
DROP TABLE t_hard PURGE;
CREATE TABLE t_hard (ID INT);
SELECT * FROM t_hard;
DECLARE
sql_ VARCHAR ( );
BEGIN
hard parse
java中的同等语句是 Statement execute()
FOR i IN LOOP
sql_ := insert into t_hard(id) values( || i || ) ;
EXECUTE IMMEDIATE sql_ ;
END LOOP;
MIT;
soft parse
java中的同等语句是 PreparedStatement execute()
sql_ := insert into t_hard(id) values(:id) ;
FOR i IN LOOP
EXECUTE IMMEDIATE sql_
USING i;
END LOOP;
MIT;
END;
正确的分页算法
SELECT *
FROM (SELECT a * ROWNUM rn
FROM (SELECT * FROM t_employees ORDER BY first_name) a
WHERE ROWNUM <= )
WHERE rn > ;
分页算法(why not this one)
SELECT a * ROWNUM rn
FROM (SELECT * FROM t_employees ORDER BY first_name) a
WHERE ROWNUM <= AND ROWNUM > ;
分页算法(why not this one)
SELECT b *
FROM (SELECT a * ROWNUM rn
FROM t_employees a
WHERE ROWNUM < =
ORDER BY first_name) b
WHERE b rn > ;
OLAP
小计合计
SELECT CASE
WHEN a deptno IS NULL THEN
合计
WHEN a deptno IS NOT NULL AND a empno IS NULL THEN
小计
ELSE
|| a deptno
END deptno
a empno
a ename
SUM(a sal) total_sal
FROM scott emp a
GROUP BY GROUPING SETS((a deptno) (a deptno a empno a ename) ());
分组排序
SELECT a deptno
a empno
a ename
a sal
可跳跃的rank
rank() over(PARTITION BY a deptno ORDER BY a sal DESC) r
密集型rank
dense_rank() over(PARTITION BY a deptno ORDER BY a sal DESC) r
不分组排序
rank() over(ORDER BY sal DESC) r
FROM scott emp a
ORDER BY a deptno a sal DESC;
当前行数据和前/后n行的数据比较
SELECT a empno
a ename
a sal
上面一行
lag(a sal) over(ORDER BY a sal DESC) lag_
下面三行
lead(a sal ) over(ORDER BY a sal DESC) lead_
FROM scott emp a
cha138/Article/program/Oracle/201311/16728相关参考
数据库进阶:循序渐进讲解SQL查询语句的高级应用技巧[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一
数据库进阶:循序渐进讲解SQL查询语句的高级应用技巧[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一
数据库进阶:循序渐进讲解SQL查询语句的高级应用技巧[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一
oracleSQL语句执行过程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Oracle中SQ
ORACLESQL判断字符串是否为数字的语句 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 记录
Oraclesql 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 前言 sql_trace是我
认识OracleSQL内置函数 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! SQL中的单记录函
SQL基本语句 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 掌握SQL四条最基本的数据*作语句
有时候我们经常为我们的sql语句执行效率低下发愁反复优化后可还是得不到提高 那么你就用这条语句找出你sql到底是在哪里慢了 示例 SETSTATISTICSioON &
SQL语句获取日期 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! SQL语句获取特定日期 一个