SQL基础培训内容

最近给公司内部非研发同学做SQL基础培训,帮助需要做数据分析,写sql提数的同学做个基础辅导

SQL(基础查询)

SQL(关联查询)

1. SQL(基础查询)

1.1. 基本查询语句

1.1.1. FROM子句

SQL查询语句的语法如下:

01.SELECT <*, column [alias], …> FROM table;

其中:SELECT用于指定要查询的列,FROM指定要从哪个表中查询。如果要查询所有列,可以在SELECT后面使用*号,如果只查询特定的列,可以直接在SELECT后面指定列名,列名之间用逗号隔开。例句如下,查询dept表中的所有记录:

01.SELECT * FROM dept;

1.1.2. 使用别名

在SQL语句中可以通过使用列的别名改变标题的显示样式,或者表示计算结果的含义,使用语法是列的别名跟在列名后,中间可以加或不加一个“AS”关键字。例如:

01.SELECT empno AS id ,ename "Name", sal * 12 "Annual Salary"  FROM emp;

别名可以直接写,不必用双引号引起来。但是如果希望别名中区分大小写字符,或者别名中包含字符或空格,则必须用双引号引起来。

1.1.3. WHERE子句

在SELECT语句中,可以在WHERE子句中使用比较操作符限制查询结果,是可选的。

当查询条件中和数字比较,可以使用单引号引起,也可以不用,当和字符及日期类型的数据比较,则必须用单引号引起。例如查询部门10下的员工信息:

01.SELECT * FROM empWHERE deptno = 10;

查询职员表中职位是’SALESMAN’的职员:

01.SELECT ename, sal, job FROM emp WHERE job = 'SALESMAN';

1.1.4. SELECT子句

如果只查询表的部分列,需要在SELECT后指定列名,例如:

01.SELECT empno, ename, sal, job FROM emp;

1.2. 查询条件

1.2.1. 使用>, <, >=, <=, !=, <>, =

在WHERE子句中的查询条件,可以使用比较运算符来做查询。比如:查询职员表中薪水低于2000元的职员信息:

01.SELECT ename, sal FROM emp WHERE sal< 2000;

查询职员表中不属于部门10的员工信息(!=等价于<>):

01.    SELECT ename, sal, job FROM emp WHERE deptno != 10;

查询职员表中在2002年1月1号以后入职的职员信息,比较日期类型数据:

01.   SELECT ename, sal, hiredate FROM emp

02.   WHERE hiredate>to_date('2002-1-1','YYYY-MM-DD');

1.2.2. 使用AND,OR关键字

02.WHERE sal> 1000 AND job = 'CLERK';

查询薪水大于1000或者职位是’CLERK’的职员信息:

01.SELECT ename, sal, job FROM emp

02.WHERE sal> 1000 OR job = 'CLERK';

1.2.3. 使用LIKE条件(模糊查询)

当用户在执行查询时,不能完全确定某些信息的查询条件,或者只知道信息的一部分,可以借助LIKE来实现模糊查询。LIKE需要借助两个通配符:

•%:表示0到多个字符

•_:标识单个字符

这两个通配符可以配合使用,构造灵活的匹配条件。例如查询职员姓名中第二个字符是‘A’的员工信息:

01.SELECT ename, job FROM emp WHERE ename LIKE '_A%';

1.2.4. 使用IN和NOT IN

在WHERE子句中可以用比较操作符IN(list)来取出符合列表范围中的数据。其中的参数list表示值列表,当列或表达式匹配于列表中的任何一个值时,条件为TRUE,该条记录则被显示出来。

IN页可以理解为一个范围比较操作符,只不过这个范围是一个指定的值列表,NOT IN(list) 取出不符合此列表中的数据记录。例如查询职位是MANAGER或者CLERK的员工:

01.SELECT ename, job FROM emp WHERE job IN ('MANAGER', 'CLERK');

查询不是部门10或20的员工:

01.SELECT ename, job FROM emp WHERE deptno NOT IN (10, 20);

1.2.5. BETWEEN…AND…

BETWEEN…AND…操作符用来查询符合某个值域范围条件的数据,最常见的是使用在数字类型的数据范围上,但对字符类型和日期类型数据也同样适用。例如查询薪水在1500-3000之间的职员信息:

01.    SELECT ename, sal FROM emp

02.    WHERE sal BETWEEN 1500 AND 3000;

1.2.6. 使用IS NULL和IS NOT NULL

空值NULL是一个特殊的值,比较的时候不能使用”=”号,必须使用IS NULL,否则不能得到正确的结果。例如查询哪些职员的奖金数据为NULL:

01.SELECT ename, sal, comm FROM emp

02.WHERE comm IS NULL;

1.2.7. 使用ANY和ALL条件

在比较运算符中,可以出现ALL和ANY,表示“全部”和“任一”,但是ALL和ANY不能单独使用,需要配合单行比较操作符>、>=、<、<=一起使用。其中:

•> ANY : 大于最小

•< ANY:小于最大

•> ALL:大于最大

•< ALL:小于最小

例如,查询薪水比职位是“SALESMAN”的人高的员工信息,比任意一个SALESMAN高都行:

01.SELECT empno, ename, job, sal, deptno

02.FROM emp

03.WHERE sal> ANY (

04.SELECT sal FROM emp WHERE job = 'SALESMAN');

1.2.8. 查询条件中使用表达式和函数

当查询需要对选出的字段进行进一步计算,可以在数字列上使用算术表达式(+、-、*、/)。表达式符合四则运算的默认优先级,如果要改变优先级可以使用括号。

算术运算主要是针对数字类型的数据,对日期类型的数据可以做加减操作,表示在一个日期值上加或减一个天数。

查询条件中使用字符串函数UPPER,将条件中的字符串变大写后再参与比较:

01.SELECT ename, sal, job FROMempWHERE ename = UPPER('rose');

查询条件中使用算数表达式,查询年薪大于10w元的员工记录:

01.SELECT ename, sal, job FROM empWHERE sal * 12 >100000;

1.2.9. 使用DISTINCT过滤重复

数据表中有可能存储相同数据的行,当执行查询操作时,默认情况会显示所有行,不管查询结果是否有重复的数据。当重复数据没有实际意义,经常会需要去掉重复值,使用DISTINCT实现。例如查询员工的部门编码,包含所有重复值:

01.SELECT deptno FROM emp;

查询员工的部门编码,去掉重复值:

01.SELECT DISTINCT deptno FROM emp;

DISTINCT后面的列可以组合查询,下例查询每个部门的职位,去掉重复值。注意是deptno和job联合起来不重复

01.SELECT DISTINCT deptno, job FROM emp;

1.3. 排序

1.3.1. 使用ORDER BY字句

对查询出的数据按一定规则进行排序操作,使用ORDER BY子句。语法如下:

注意,ORDER BY必须出现在SELECT中的最后一个子句。下例对职员表按薪水排序:

01.SELECT ename, sal

02.FROM emp

03.ORDER BY sal;

1.3.2. ASC和DESC

排序时默认按升序排列,即由小及大,ASC用来指定升序排序,DESC用来指定降序排序

因为NULL值视作最大,则升序排列时,排在最后,降序排列时,排在最前。如果不写ASC或DESC,默认是ASC,升序排列。例如,按员工的经理升序排序:

01.    SELECT empno, ename, mgr FROM emp

02.    WHERE deptno = 10 ORDER BY mgr;

降序排列,必须指明,按员工的薪水倒序排序:

01.    SELECT ename, sal FROM emp

02.    ORDER BY sal DESC;

1.3.3. 多个列排序

当以多列作为排序标准时,首先按照第一列进行排序,如果第一列数据相同,再以第二列排序,以此类推。多列排序时,不管正序还是倒序,每个列需要单独设置排序方式。

01.    SELECT ename, deptno, sal FROM emp

02.    ORDER BY deptno ASC, sal DESC;

1.4. 聚合函数

1.4.1. 什么是聚合函数

查询时需要做一些数据统计,比如:查询职员表中各部门职员的平均薪水,各部门的员工人数。当需要统计的数据并不能在职员表里直观列出,而是需要根据现有的数据计算得到结果,这种功能可以使用聚合函数来实现,即:将表的全部数据划分为几组数据,每组数据统计出一个结果。

因为是多行数据参与运算返回一行结果,也称作分组函数、多行函数、集合函数。用到的关键字:

•GOURP BY 按什么分组

•HAVING 进一步限制分组结果

1.4.2. MAX和MIN

用来取得列或表达式的最大、最小值,可以用来统计任何数据类型,包括数字、字符和日期。例如获取机构下的最高薪水和最低薪水,参数是数字:

01.SELECT MAX(sal) max_sal, MIN(sal) min_sal

02.FROM emp;

计算最早和最晚的入职时间,参数是日期:

01.SELECT MAX(hiredate) max_hire, MIN(hiredate) min_hire

02.FROM emp;

1.4.3. AVG和SUM

AVG和SUM函数用来统计列或表达式的平均值和和值,这两个函数只能操作数字类型,并忽略NULL值。例如获得机构下全部职员的平均薪水和薪水总和:

01.SELECT AVG(sal) avg_sal, SUM(sal)  sum_sal  FROM emp;

1.4.4. COUNT

COUNT函数用来计算表中的记录条数,同样忽略NULL值。例如获取职员表中一共有多少名职员记录:

01.SELECT COUNT(*) total_num  FROM emp;

获得职员表中有多少人是有职位的(忽略没有职位的员工记录)

01.    SELECT COUNT(job) total_job  FROM emp;

1.4.5. 聚合函数对空值的处理

聚合函数忽略NULL值。即当emp表中的某列有NULL值,比如某新入职员工没有薪水,比较两条语句的结果:

01.SELECT AVG(sal)  avg_sal FROM emp;

02.SELECT AVG(NVL(sal,0)) avg_sal FROM emp;

1.5. 分组

1.5.1. GROUP BY子句

上面的例子都是以整个表作为一组。如果希望得到每个部门的平均薪水,而不是整个机构的平均薪水,需要把整个数据表按部门划分成一个个小组,每个小组中包含一行或多行数据,在每个小组中再使用分组函数进行计算,每组返回一个结果。语法如下:

01.SELECT <*, column [alias], …>

02.FROM table [WHERE condition(s)]

03.[GROUP BY group_by_expression]

04.[HAVING group_condition]

05.[ORDER BY column [ASC | DESC]] ;

其中划分的小组有多少,最终的结果集行数就有多少。

1.5.2. 分组查询

1.5.3. HAVING字句

HAVING子句用来对分组后的结果进一步限制,比如按部门分组后,得到每个部门的最高薪水,可以继续限制输出结果。必须跟在GROUP BY后面,不能单独存在。例如查询每个部门的最高薪水,只有最高薪水大于4000的记录才被输出显示:

01.SELECT deptno, MAX(sal) max_sal FROM emp

02.GROUP BY deptno HAVING MAX(sal) >4000;

1.6. 查询语句的执行顺序

当一条查询语句中包含所有的子句,执行顺序依下列子句次序:

1.FROM 子句:执行顺序为从后往前、从右到左。数据量较少的表尽量放在后面。

2.WHERE子句:执行顺序为自下而上、从右到左。将能过滤掉最大数量记录的条件写在WHERE 子句的最右。

3.GROUP BY:执行顺序从左往右分组,最好在GROUP BY前使用WHERE将不需要的记录在GROUP BY之前过滤掉。

4.HAVING 子句:消耗资源。尽量避免使用,HAVING 会在检索出所有记录之后才对结果集进行过滤,需要排序等操作。

5.SELECT子句:少用*号,尽量取字段名称。ORACLE 在解析的过程中, 通过查询数据字典将*号依次转换成所有的列名, 消耗时间。

6.ORDER BY子句:执行顺序为从左到右排序,消耗资源。

2.1. 关联基础

2.1.1. 关联的概念

实际应用中所需要的数据,经常会需要查询两个或两个以上的表。这种查询两个或两个以上数据表或视图的查询叫做连接查询,连接查询通常建立在存在相互关系的父子表之间。语法如下:

01.SELECT table1.column, table2.column

02.FROM table1, table2

03.WHERE table1.column1 = table2.column2;

或者:

01.SELECT table1.column, table2.column

02.FROM table1JOIN table2

03.ON(table1.column1 = table2.column2);

 

 

 

2.1.2. 笛卡尔积

笛卡尔积指做关联操作的每个表的每一行都和其它表的每一行做组合,假设两个表的记录条数分别是X和Y,笛卡尔积将返回X * Y条记录。当两个表关联查询时,不写连接条件,得到的结果即是笛卡尔积。例如:

01.SELECT COUNT(*) FROM emp; --14条记录

02.SELECT COUNT(*) FROM dept; --4条记录

03.SELECT emp.ename, dept.dnameFROM emp, dept;--56条记录

2.1.3. 等值连接

等值连接是连接查询中最常见的一种,通常是在有主外键关联关系的表间建立,并将连接条件设定为有关系的列,使用等号”=”连接相关的表。例如查询职员的姓名、职位以及所在部门的名字和所在城市,使用两个相关的列做等值操作:

01.SELECT e.ename, e.job, d.dname, d.loc

02.FROM emp e, dept d

03.WHERE e.deptno = d.deptno;

2.2. 关联查询

2.2.1. 内连接

内连接返回两个关联表中所有满足连接条件的记录。例如查询员工的名字和所在部门的名字:

01.SELECT e.ename, d.dname

02.FROM emp e, dept d

03.WHERE e.deptno = d.deptno

上面的语法也可以写为:

01.SELECT e.ename, d.dname

02.FROM emp e JOIN dept d

03.ON(e.deptno = d.deptno);

2.2.2. 外连接

内连接返回两个表中所有满足连接条件的数据记录,在有些情况下,需要返回那些不满足连接条件的记录,需要使用外连接,即不仅返回满足连接条件的记录,还将返回不满足连接条件的记录。比如把没有职员的部门和没有部门的职员查出来。外连接的语法如下:

01.SELECT table1.column, table2.column

02.FROM table1 [LEFT | RIGHT | FULL] JOIN table2

03.ON table1.column1 = table2.column2;

了解驱动表的概念。

    

 

  1. 外连接查询的例子,Emp表做驱动表:

01.SELECT e.ename, d.dname

02.FROM emp e LEFT OUTER JOIN dept d

03.ON e.deptno = d.deptno;

  1. Dept表做驱动表:

01.SELECT e.ename, d.dname

02.FROM emp e RIGHT OUTER JOIN dept d

03.ON e.deptno = d.deptno;

 

2.2.3. 全连接

全外连接是指除了返回两个表中满足连接条件的记录,还会返回不满足连接条件的所有其它行。即是左外连接和右外连接查询结果的总和。例如:

01.SELECT e.ename, d.dname

02.FROM emp e FULL OUTER JOIN dept d

03.ON e.deptno = d.deptno;

http://pdf7.tarena.com.cn/tts8_source/ttsPage/JAVA/JSD_N_V06/ORACLE/DAY03/SUPERDOC/01/index.files/image009.png

2.2.4. 自连接

自连接是一种特殊的连接查询,数据的来源是一个表,即关联关系来自于单表中的多个列。表中的列参照同一个表中的其它列的情况称作自参照表。

自连接是通过将表用别名虚拟成两个表的方式实现,可以是等值或不等值连接。例如查出每个职员的经理名字,以及他们的职员编码:

01.SELECT worker.empnow_empno, worker.enamew_ename, manager.empnom_empno, manager.enamem_ename

02.FROM emp worker join emp manager

03.ON worker.mgr = manager.empno;

  • SQL(高级查询)

1.1. 子查询

1.1.1. 子查询在WHERE子句中

SELECT查询中,在WHERE查询条件中的限制条件不是一个确定的值,而是来自于另外一个查询的结果。为了给查询提供数据而首先执行的查询语句叫做子查询。

子查询:嵌入在其它SQL语句中的SELECT语句,大部分时候出现在WHERE子句中。子查询嵌入的语句称作主查询或父查询。主查询可以是SELECT语句,也可以是其它类型的语句比如DML或DDL语句。

根据返回结果的不同,子查询可分为单行子查询、多行子查询及多列子查询

  1. 图示:

例如查找和SCOTT同职位的员工:

01.SELECT e.ename, e.job

02.FROM emp e

03.WHERE e.job =

04.  (SELECT job FROM emp WHERE ename = 'SCOTT')

如果子查询返回多行,主查询中要使用多行比较操作符,包括IN、ALL、ANY。其中ALL和ANY不能单独使用,需要配合单行比较操作符>、>=、<、<=一起使用。

例如查询出部门中有SALESMAN但职位不是SALESMAN的员工的信息:

01.SELECT empno, ename, job, sal, deptno

02.FROM emp

03.WHERE deptno IN

04.(SELECT deptno FROM emp WHERE job = 'SALESMAN')

05.AND job <> 'SALESMAN';

在子查询中需要引用到主查询的字段数据,使用EXISTS关键字。EXISTS后边的子查询至少返回一行数据,则整个条件返回TRUE。如果子查询没有结果,则返回FALSE。例如列出来那些有员工的部门信息:

01.SELECT deptno, dname FROM dept d

02.WHERE EXISTS

03.        (SELECT * FROM emp e

04.         WHERE d.deptno = e.deptno);

1.1.2. 子查询在HAVING部分

 

子查询不仅可以出现在WHERE子句中还可以出现在HAVING部分

例如查询列出最低薪水高于部门30的最低薪水的部门信息:

01.SELECT deptno, MIN(sal) min_sal

02.FROM emp

03.GROUP BY deptno

04.HAVING MIN(sal) >

05.(SELECT MIN(sal) FROM emp WHERE deptno = 30);

1.1.3. 子查询在FROM部分

在查询语句中,FROM子句用来指定要查询的表。如果要在一个子查询的结果中继续查询,则子查询出现在FROM 子句中,这个子查询也称作行内视图或者匿名视图。这时,把子查询当作视图对待,但视图没有名字,只能在当前的SQL语句中有效。

查询出薪水比本部门平均薪水高的员工信息:

01.SELECT e.deptno, e.ename, e.sal

02.FROM emp e,

03.(SELECT deptno, AVG(sal) avg_sal FROM emp GROUP BY deptno) x

04.WHERE e.deptno = x.deptno

05.ande.sal>x.avg_sal

06.ORDER BY e.deptno;

1.1.4. 子查询在SELECT部分

把子查询放在SELECT子句部分,可以认为是外连接的另一种表现形式,使用更灵活:

01.SELECT e.ename, e.sal, e.deptno,

02.           (SELECT d.deptno FROM dept d

03.            WHERE d.deptno = e.deptno)  deptno

04.FROM emp e;

1.2. 分页查询

1.2.1. LIMIT

初始记录行的偏移量是 0(而不是 1):
SELECT * FROM table LIMIT 5,10; //检索记录行6-15

如果只给定一个参数,它表示返回最大的记录行数目。换句话说,LIMIT n 等价于 LIMIT 0,n:
SELECT * FROM table LIMIT 5;     //检索前 5 个记录行

1.2.2. OFFSET

从数据库中的第二条数据开始查询两条数据,即第二条和第三条

selete * from table limit 2 offset 1

1.3. 集合操作

1.3.1. UNION、UNION ALL

为了合并多个SELECT语句的结果,可以使用集合操作符,实现集合的并、交(mysql使用in实现)、差(mysql使用not in实现)

集合操作符包括UNION、UNION ALL、INTERSECT和MINUS(mysql不支持)。多条作集合操作的SELECT语句的列的个数和数据类型必须匹配。

ORDER BY子句只能放在最后的一个查询语句中。

集合操作的语法如下:

01.SELECT statement1

02.[UNION | UNION ALL | INTERSECT | MINUS]

03.SELECT statement2;

UNION和UNION ALL用来获取两个或两个以上结果集的并集:

•UNION操作符会自动去掉合并后的重复记录。

•UNION ALL返回两个结果集中的所有行,包括重复的行。

•UNION操作符对查询结果排序,UNION ALL不排序。

例如,合并职位是’MANAGER’的员工和薪水大于2500的员工集合,查看两种方式的结果差别:

01.--Union

02.SELECT ename, job, sal FROM emp

03.WHERE job = 'MANAGER'

04.SELECT ename, job, sal FROM emp

05.WHERE sal> 2500;

06.

07.--Union all

08.SELECT ename, job, sal FROM emp

09.WHERE job = 'MANAGER'

10.SELECT ename, job, sal FROM emp

11.WHERE sal> 2500;

 

 

 

 

 

1.4. 控制流程函数

1.4.1. CASE WHEN函数

函数基本语法

DECODE函数的语法如下:

CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ……] [ELSE result ] END

CASE WHEN [condition] THEN result [WHEN[condition] THENresult ……][ELSE result] END

函数用法说明:在第一个方案的返回结果中, value=compare-value 。而第二个方案的返回 结果是第一种情况的真实结果。如果没有匹配的结果值,则返回结果为 ELSE 后的结果, 如果没有 ELSE 部分,则返回值为 NULL

函数的应用

Select CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END from emp;

Select CASE WHEN sex = '1' THEN '男' WHEN sex = '2' THEN '女' ELSE '其他' END from emp;

1.4.2. IF

函数基本语法

语法: IF(expr1,expr2,expr3)

函数用法说明:如果 expr1 是 TRUE (expr1 <> 0and expr1 <> NULL) ,则 IF() 的返回值 为 expr2 ; 否则返回值则为 expr3 。 IF() 的返回值为数字值或字符串值,具体情况视其所 在语境而定场景:按照部门编码分组显示,每组内按职员编码排序,并赋予组内编码  

函数的应用

select *,if(sva=1,"男","女") as ssva FROM emp;

 

1.4.3. IFNULL

函数基本语法

语法: IFNULL(expr1,expr2)

函数用法说明:假如 expr1 不为 NULL ,则 IFNULL() 的返回值为 expr1; 否则其返回值 为 expr2 。 IFNULL() 的返回值是数字或是字符串,具体情况取决于其所使用的语境,

函数的应用

Select IFNULL(sex,1) FROM emp;

 

1.5. 字符串函数

1.5.1. CONCAT

函数基本语法

CONCAT(str1,str2,...) 返回来自于参数连结的字符串。如果任何参数是NULL,返回 NULL。可以有超过2 个的参数。一个数字参数被变换为等价的字符串形式

函数的应用

mysql>selectCONCAT('My','S','QL');

->'MySQL'

 

mysql>selectCONCAT('My',NULL, 'QL');

->NULL

 

mysql>selectCONCAT(14.3);

->'14.3'

 

1.5.2. SUBSTRING

函数基本语法

SUBSTRING(str,pos,len)

从字符串str 返回一个len 个字符的子串,从位置pos 开始

函数的应用

mysql>selectSUBSTRING('Quadratically',5,6);

->'ratica

 

1.5.3. FIND_IN_SET

函数基本语法

如果字符串 str 在由 N 子串组成的表strlist 之中,返回一个 1 到 N 的值。一个字符串表是被“,”分隔的子串组成的一个字 符串。如果第一个参数是一个常数字符串并且第二个参数是一种类型为SET 的列,FIND_IN_SET()函数被优化而使用位 运算!如果 str 不是在 strlist 里面或如果 strlist 是空字符串,返回 0。如果任何一个参数是 NULL,返回 NULL。如果第一个参数包含一个“,”,该函数将工作不正常。

函数的应用

mysql>SELECTFIND_IN_SET('b','a,b,c,d');

->2

 

 

1.6. 时间函数

1.6.1. UNIX_TIMESTAMP

函数基本语法

UNIX_TIMESTAMP(date) 如果没有参数调用,返回一个 Unix 时间戳记(从'1970-01-01 00:00:00'GMT 开始的秒数)。如果 UNIX_TIMESTAMP()用一个 date 参数被调用,它返回从 '1970-01-01 00:00:00' GMT 开始的秒数值。date 可以是一个 DATE 字符串、一 个 DATETIME 字符串、一个 TIMESTAMP 或以 YYMMDD 或 YYYYMMDD 格式的本地时间 的一个数字

函数的应用

mysql> select UNIX_TIMESTAMP();

-> 1539237768

 

mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');

-> 875996580

1.6.1. FROM_UNIXTIME

函数基本语法

FROM_UNIXTIME(unix_timestamp) 以'YYYY-MM-DD HH:MM:SS'或 YYYYMMDDHHMMSS 格式返回 unix_timestamp 参 数所表示的值,取决于函数是在一个字符串还是或数字上下文中被使用。

函数的应用

mysql> select FROM_UNIXTIME(875996580);

 -> '1997-10-04 22:23:00'

 

 

  • SQL(其他操作)
    1. 新增记录

Insert into emp(dept,sex) values(1,1);

 

1.2、修改记录

update emp set dept=2 where id=1

 

1.3、删除记录

 

delete * from emp where id=1

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1 SQL基础 1.1 基本概念 结构化查询语言(Structured Query Language)简称SQL,是一种关系数据库查询语言,用于存取数据以及查询、更新和管理关系数据库系统。 1.2 语句结构 1.2.1 数据查询语言(DQL) 对数据库进行的信息查询,select。 1.2.2 数据操作语言(DML) 用于操作关系型数据库对象内部的数据,insert、update、delete。 1.2.3 数据定义语言(DDL) 用来建立及定义数据表、字段以及索引等数据库结构,create、alter、drop 。 1.2.4 数据控制语言(DCL) 用于控制对数据库里数据的访问,通常用于创建与用户访问相关的对象以及控制用户的权限,grant、revoke(撤销)。 1.2.5 事务控制命令(TPL) 用于管理数据库事务,commit、rollback、savepoint(在一组事务里创建标记点以用于回退)。 1.3 表的构成 1.3.1 字段 字段是表里的一列,用于保持每条记录的特定信息 1.3.2 记录 记录,也被成为一行数据,是表里的每一行 1.4 完整性的约束条件 1.4.1 实体完整性 关系模型的实体完整性在create table中用primary key约束实现,primary key约束用于定义主键,它保证主键的唯一性和非空性。 1.4.2 参照完整性 关系模型的参照完整性可以通过在create table中用foreign key (<外键>) references <被参照表名> (<与外键对应的主键名>)进行约束定义。 1.4.3 用户定义完整心 在create table语句中可以根据应用要求,定义属性以及元组上的约束。 常见的用户定义的完整性约束有: not null或null约束。 unique约束:唯一性约束。 default约束:默认值约束。 check约束:检查约束,check约束通过约束条件表达式设置列值应该满足的条件。 1.5 范式 1.5.1 第一范式 1.5.1.1 规范 无重复的列,确保每列保持原子性,即数据库表中的所有字段值都是不可分解的原子值。 1.5.1.2 举例 姓名 年龄 联系电话 地址 省 市 详细地址 1.5.2 第二范式 1.5.2.1 规范 属性完全依赖于主键,确保表中每列都与主键相关。 1.5.2.2 举例 订单表 订单Id 商品Id 总金额 商品名称 001 1 10 苹果 001 2 10 橘子 联合主键订单Id、商品Id => 商品表 商品Id 商品名称 单价 订单表 订单Id 总金额 1.5.3 第三范式 1.5.3.1 规范 属性不依赖于其它非主属性,确保数据表中的每一列数据都和主键直接相关,而不能间接相关,即要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。 1.5.3.2 举例 党员表 党员Id 党员姓名 组织Code 符合3NF 党员表 党员Id 党员姓名 组织名称 不符合3NF 组织表 组织Code 组织名称 1.6 外连接 1.6.1 准备 create table student_A( uuid varchar2(32), name varchar2(100)); create table student_B( uuid varchar2(32), name varchar2(100)); insert into student_A values('1','小黄'); insert into student_A values('2','小黑'); insert into student_A values('3','小红'); insert into student_B values('1','大黄'); insert into student_B values('2','大黑'); insert into student_B values('4','大红'); insert into student_B values('4','大紫'); 1.6.2 左连接(left join) 1.6.2.1 说明 查询指定的左表的所有行,而不仅仅是联接列所匹配的行;如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。 1.6.2.2 语法 select A.*,B.* from student_A A left join student_B B on A.Uuid = B.Uuid; 1.6.2.3 结果 1.6.2.4 (+)表示 select A.*,B.* from student_A A,student_B B where A.Uuid = B.Uuid(+) 1.6.3 右连接(right join) 1.6.3.1 说明 查询指定的右表的所有行,而不仅仅是联接列所匹配的行;如果右表的某行在左表中没有匹配行,则在相关联的结果集行中左表的所有选择列表列均为空值。 1.6.3.2 语法 select A.*,B.* from student_A A right join student_B B on A.Uuid = B.Uuid; 1.6.3.3 结果 1.6.3.4 (+)表示 select A.*,B.* from student_A A,student_B B where A.Uuid(+) = B.Uuid 1.6.4 全外连接(full outer join) 1.6.4.1 说明 完整外部联接返回左表和右表中的所有行;当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值;如果表之间有匹配行,则整个结果集行包含基表的数据值。 1.6.4.2 语法 select A.*, B.* from student_A A full outer join student_B B on A.Uuid = B.Uuid; 1.6.4.3 结果 1.6.4.4 全外连接不支持(+)写法 1.6.5 (+) + 表示补充,即哪个表有加号,这个表就是匹配表。 1.7 运算符 1.7.1 比较 =、>,<,>=,<=,!=,<>, 1.7.2 确定范围 between and 、not between and 1.7.3 确定集合 in、not in 1.7.4 字符匹配 like(“%”匹配任何长度,“_”匹配一个字符) 1.7.5 转义字符 1.7.5.1 常规转义字符 “\”转义字符,“\%”则表示单纯的字符“%” 1.7.5.2 escape escape关键字经常用于使某些特殊字符,如通配符:'%','_'转义为它们原来的字符的意义,被定义的转义字符通常使用'\',但是也可以使用其他的符号。 select * from Student_a where name like '%$%%' escape '$'; 1.7.6 空值 is null、is not null 1.7.7 集合查询 union(并)、intersect(交)、minus(差) 1.7.8 多重条件 and、or、not 1.7.9 对查询结果分组 <group by 列名> 1.7.10 分组筛选条件 [having <条件表达式>] 1.7.11 字符串拼接 select 'A' || 'B' from dual; // || 拼接 1.8 函数 1.8.1 聚集函数 count、sum、avg、max、min 1.8.2 case when 1.8.2.1 语法 select t.uuid, t.score, case when t.score > 90 then '优秀' when t.score > 60 then '及格' else '不及格' end from exam_user_exam t 1.8.3 decode 1.8.3.1 语法 select decode(x,1,'x is 1', 2 , 'x is 2','others') from dual 1.8.3.2 说明 当x等于1时,则返回‘x is 1’,当x等于2时,则返回‘x is 2’,否则,返回‘others’。 1.8.4 nulls first(nulls last)排序 1.8.4.1 语法 select * from dy_info t order by t.degree nulls first 1.8.4.2 说明 控制null显示行位置 1.8.5 Nvl 1.8.5.1 语法 select nvl(t.sap,'空') from dy_info t; 1.8.5.2 说明 如果sap号为空,则返回‘空’,否则返回sap号。 1.8.6 递归查询 1.8.6.1 语法 select t.* from g_organ t start with t.organcode = '080' connect by prior t.parentcode = t.organcode; //递归查询父节点 select t.* from g_organ t start with t.organcode = '080' connect by t.parentcode = prior t.organcode; //递归查询子节点 1.8.7 union 和 union all 1.8.7.1 语法 select * from dual union all select * from dual 1.8.7.2 说明 union 会对查询数据进行去重并排序,union all只是简单的将两个结果合并。 1.8.8 wm_concat 1.8.8.1 语法 select wm_concat(t.role_name) from g_role t where t.role_name like '%书记%' 1.8.8.2 说明 拼接字符串,结果为:‘党工委副书记,总支副书记,党支部书记,党委书记,党委副书记,党总支书记,党工委书记,党总支副书记,党支部副书记’ 1.8.9 相似度 1.8.9.1 语法 select utl_match.edit_distance_similarity('aaaaa','bbaaaa') from dual; 1.8.10 去格式 1.8.10.1 oracle正则表达式:去除<></>格式 select REGEXP_REPLACE(title,'<[^>]*>','') title from exam_question 1.8.11 rank() over (partition by …) 1.8.11.1 语法 select organcode,score,ranknum from ( select t.organcode, t.score, rank() over (partition by t.organcode order by t.score desc) ranknum from exam_user_exam t) where ranknum < 4 1.8.11.2 说明 获取每个组织,考试成绩前三名。 1.9 存储过程 1.9.1 定义 存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。 1.9.2 准备 create table t_user ( username varchar2(20), password varchar2(20) ); create table t_user_temp ( username varchar2(20), password varchar2(20) ); insert into t_user(username,password) values('小王','1111'); insert into t_user(username,password) values('小李','1111'); 1.9.3 创建存储过程 create or replace procedure adduser as begin insert into t_user_temp(username,password) select username,password from t_user t where t.username = '小李'; end adduser; 1.9.4 执行 begin adduser; end; 1.9.5 验证 select * from t_user; select * from t_user_temp 2 SQL深入 2.1 常用 2.1.1 表空间 2.1.1.1 创建表空间 create tablespace TS_DJY datafile 'd:/software/oracle/tablespace/ts_djy.dat' size 1024M autoextend on next 100M maxsize 2048M; 2.1.1.2 指定用户表空间 alter user cssdj default tablespace TS_DJY; 2.1.1.3 指定表的表空间 create table t_student( uuid varchar2(32) )tablespace TS_DJY; 2.1.2 自增sequence 2.1.2.1 创建 create sequence seq_student_uuid minvalue 1 maxvalue 999999999999999 start with 1 increment by 1 nocache; 2.1.2.2 使用 select seq_student_uuid.nextval from dual; //获取下一个 select seq_student_uuid.currval from dual; //获取当前 2.1.3 批量插入 2.1.3.1 查询结果批量插入 insert into tablea(cola,colb) select cola,colb from tableb; 2.1.3.2 创建相同的表结构并插入数据(备份表数据) create tab_new as select * from tab_old; 2.1.3.3 创建相同的表结构不插入数据 create tab_new as select * from tab_old where rownum=0; 2.1.4 伪列伪表 2.1.4.1 伪列 伪列不是表的真实列,但是你可以象使用真实列一样使用伪列,常用伪列:rowid行的绝对物理编号,每一行是唯一的。rownum序号,返回查询结果的每行序号。系统时间sysdate,返回系统当前时间。 2.1.4.2 伪表 select * from dual; 2.1.5 系统表 2.1.5.1 user_tables 当前用户表信息 2.1.5.2 user_tab_columns 当前用户表所有列信息,搜索列所在的表: select * from user_tab_columns t where t.column_name like '%ORGANCODE%'; 2.1.5.3 user_tablespaces 当前用户表空间 2.1.5.4 dba_users 数据库所有用户 2.1.5.5 dba_tables 数据库所有表 2.1.5.6 dba_tablespaces 数据库所有表空间 2.1.6 锁表解锁 2.1.6.1 查看锁表信息 select l.OBJECT_ID,s.SID,s.SERIAL#,s.USERNAME, s.MACHINE from V$locked_Object l,V$session s where l.SESSION_ID = s.SID; 2.1.6.2 解锁 alter system kill session 'sid,serial#'; 2.1.7 备份与恢复 2.1.7.1 导出 导出用户: exp cssdj/cssdj@zr owner=(cssdj,cssdj_zsy) file=d:/cssdj.dmp log=d:/cssdj.log 导出用户表: exp cssdj/cssdj@zr tables=(g_dict,g_dict_item) file=d:/cssdj.dmp log=d:/cssdl.log 2.1.7.2 导入 imp cssdj/cssdj@zr fromuser=cssdj_zsy touser=cssdj file=d:/cssdj.cmp log=d:/cssdj.log 2.1.7.3 数据泵 2.1.8 Dblink 2.1.8.1 创建 create database link orcllink connect to cssdj identified by cssdj using '(DESCRIPTION = (ADDRESS_LIST= (ADDRESS=(PROTOCOL = TCP)(HOST = 219.239.110.65)(PORT = 1521))) (CONNECT_DATA=(SID = orcl)))'; 2.1.8.2 删除 drop database link orcllink; 2.1.8.3 使用 select * from dy_info@orcllink; 2.2 Oracle与Mysql差异 2.2.1 Group by 2.2.1.1 Oracle select后面出现的列,如果没有使用集合函数,必须出现在group by 中。 select sno,sname,sum(grade) from student group by sno,sname; //合法写法 select sno,sname,sum(grade) from student group by sno; //非法写法 select sno,min(sname),sum(grade) from student group by sno; //建议用这种写法,效率高些 2.2.1.2 Mysql select sno,sname,sum(grade) from student group by sno,sname; //合法写法 select sno,sname,sum(grade) from student group by sno; //合法写法 2.2.2 分页 2.2.2.1 Oracle 使用rownum来表明分页位置,而且rownum只能小于某值,不能大于某值,故而rownum和where联用才能完成数据范围的控制 2.2.2.2 Mysql mysql的分页可以用limit startNum,pageNum 2.3 了解 2.3.1 事务 2.3.1.1 Rollback start transaction; --开始事务 insert into g_dict values('test','测试','1',''); --执行数据操作语言(DML) select * from g_dict where code = 'test'; --可以查看是否执行正确 rollback; --错误执行rollback操作 commit; --正确执行commit操作 2.3.1.2 Savepoint start transaction; --开始事务 insert into g_dict values('t1','测试','1',''); --执行数据操作语言(DML) savepoint pointA; insert into g_dict values('t2','测试','1',''); --执行数据操作语言(DML) select * from g_dict where code = 'test33'; --可以查看是否执行正确 rollback to savepoint pointA; 2.3.2 利用执行计划评估SQL语句的性能 2.3.2.1 工具 在PL/SQL Developer中写好一段SQL代码后,按F5,PL/SQL Developer会自动打开执行计划窗口,显示该SQL的执行计划。 2.3.2.2 查看总COST,获得资源耗费的总体印象 一般而言,执行计划第一行所对应的COST(即成本耗费)值,反应了运行这段SQL的总体估计成本,单看这个总成本没有实际意义,但可以拿它与相同逻辑不同执行计划的SQL的总体COST进行比较,通常COST低的执行计划要好一些。 2.3.2.3 了解执行计划的执行步骤 按照从左至右,从上至下的方法,了解执行计划的执行步骤; 执行计划按照层次逐步缩进,从左至右看,缩进最多的那一步,最先执行,如果缩进量相同,则按照从上而下的方法判断执行顺序,可粗略认为上面的步骤优先执行。每一个执行步骤都有对应的COST,可从单步COST的高低,以及单步的估计结果集(对应ROWS/基数),来分析表的访问方式,连接顺序以及连接方式是否合理。 2.3.2.4 分析表的访问方式 表的访问方式主要是两种:全表扫描(TABLE ACCESS FULL)和索引扫描(INDEX SCAN),如果表上存在选择性很好的索引,却走了全表扫描,而且是大表的全表扫描,就说明表的访问方式可能存在问题;若大表上没有合适的索引而走了全表扫描,就需要分析能否建立索引,或者是否能选择更合适的表连接方式和连接顺序以提高效率。 2.3.2.5 分析表的连接方式和连接顺序 表的连接顺序:就是以哪张表作为驱动表来连接其他表的先后访问顺序。 表的连接方式:简单来讲,就是两个表获得满足条件的数据时的连接过程。主要有三种表连接方式,嵌套循环(NESTED LOOPS)、哈希连接(HASH JOIN)和排序-合并连接(SORT MERGE JOIN)。我们常见得是嵌套循环和哈希连接。 嵌套循环:最适用也是最简单的连接方式。类似于用两层循环处理两个游标,外层游标称作驱动表,Oracle检索驱动表的数据,一条一条的代入内层游标,查找满足WHERE条件的所有数据,因此内层游标表中可用索引的选择性越好,嵌套循环连接的性能就越高。 哈希连接:先将驱动表的数据按照条件字段以散列的方式放入内存,然后在内存中匹配满足条件的行。哈希连接需要有合适的内存,而且必须在CBO优化模式下,连接两表的WHERE条件有等号的情况下才可以使用。哈希连接在表的数据量较大,表中没有合适的索引可用时比嵌套循环的效率要高。 2.3.3 优化器 Oracle优化器分为基于规则的优化器(RBO)和基于代价的优化器(CBO)。 2.3.3.1 规则的优化器(RBO) RBO的优化方式,依赖于一套严格的语法规则,只要按照规则写出的语句,不管数据表和索引的内容是否发生变化,不会影响PL/SQL语句的"执行计划"。 2.3.3.2 基于代价的优化器(CBO) CBO计算各种可能"执行计划"的"代价",即cost,从中选用cost最低的方案,作为实际运行方案。各"执行计划"的cost的计算根据,依赖于数据表中数据的统计分布,ORACLE数据库本身对该统计分布是不清楚的,须要分析表和相关的索引,才能搜集到CBO所需的数据。 2.3.4 表分析analysis 2.3.4.1 说明 analyze table,一般可以指定分析表、所有字段、所有索引字段、所有索引,若不指定则全部都分析。 2.3.4.2 表分析 analyze table dy_info compute statistics; 2.3.4.3 删除分析数据 analyze table dy_info delete statistics; 2.3.5 oracle添加强制索引 如果使用的是CBO的话,可能SQL不执行索引,则可以添加强制索引执行索引。 2.3.5.1 语法 /*+index(tablename indexname)*/ 2.3.5.2 举例 select /*+index(t INDEX_SAP)*/* from dy_info t where t.sap = 'T6000890'
Oracle培训文档是指为了帮助用户学习和了解Oracle数据库系统而编写的一份文件。这份文档可以包含各种各样的信息和知识,从基础概念到高级应用,都可以涉及其中。 首先,Oracle培训文档可能会详细介绍Oracle数据库系统的基本概念和架构,包括数据库实例、表空间、数据文件、表、索引等等。这些基础知识对于理解和使用Oracle数据库系统非常重要。 其次,Oracle培训文档可能会提供关于如何安装和配置Oracle数据库的详细步骤和指导。这些步骤通常包括软件下载、安装、创建数据库实例以及进行一些必要的配置调整等等。在学习使用Oracle数据库之前,正确地安装和配置数据库是必不可少的。 此外,Oracle培训文档可能会涵盖如何使用SQL和PL/SQL编程语言来与Oracle数据库进行交互和操作。这些知识将教会用户如何创建表、插入、更新和删除数据,以及如何编写存储过程、触发器和函数等等。这些编程技能对于开发和管理Oracle数据库非常有帮助。 最后,Oracle培训文档也可能包含有关性能优化、备份和恢复、容灾和高可用性等方面的内容。这些知识将教会用户如何通过调整参数、优化查询语句、创建备份和恢复策略等来提高数据库的性能和可靠性。 总之,Oracle培训文档是帮助用户学习和理解Oracle数据库系统的一份重要资料,通过阅读和实践,用户可以逐步掌握Oracle数据库的基本概念、安装配置、编程技能以及高级应用等方面的知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码者人生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值