知识大全 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]

数据库进阶:循序渐进讲解SQL查询语句的高级应用技巧[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 循序渐进讲解SQL查询语句的高级应用技巧[3]

数据库进阶:循序渐进讲解SQL查询语句的高级应用技巧[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 循序渐进讲解SQL查询语句的高级应用技巧[2]

数据库进阶:循序渐进讲解SQL查询语句的高级应用技巧[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 oracleSQL语句执行过程

oracleSQL语句执行过程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Oracle中SQ

知识大全 ORACLESQL判断字符串是否为数字的语句

ORACLESQL判断字符串是否为数字的语句  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  记录

知识大全 Oraclesql

Oraclesql  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  前言  sql_trace是我

知识大全 认识OracleSQL内置函数

认识OracleSQL内置函数  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  SQL中的单记录函

知识大全 SQL基本语句

SQL基本语句  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  掌握SQL四条最基本的数据*作语句

知识大全 测试sql语句性能

  有时候我们经常为我们的sql语句执行效率低下发愁反复优化后可还是得不到提高  那么你就用这条语句找出你sql到底是在哪里慢了  示例  SETSTATISTICSioON  &

知识大全 SQL语句获取日期

SQL语句获取日期  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  SQL语句获取特定日期  一个