SQL汇总

1.SQL执行顺序

(8)SELECT (9)DISTINCT  (11)<Top Num> <select list>
(1)FROM [left_table]
(3)<join_type> JOIN <right_table>
(2)        ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list> 

2.查询

SELECT 列名称 FROM 表名称 WHERE 列 运算符 值
select * from table
where  A #单个条件
where  A and B #和
where  A or B  #或
where  (A and B) or (C and D)  #优先级
where  in (" "," “," ”)  #指定针对某个列的多个可能值
where  A>>=<<=!=10000  #单个数值
where A between 10000 and 20000 #在某个范围内
where A like%B%’  #模糊查询/搜索某种模式
where A not innot likenot null  #否定
sign--符号,power--幂

3.分组

select * from table
group by A  #将数据按组/维度划分
select * from table
group by A ,B #将数据按多维形式聚合
select A,count(*) as 客户数量 
from table
group by A  #统计数量

除了count,还有max,min,sum,avg等函数,也叫做聚合函数

select A,count(distinct Id) from table
group by A #按A分组(不重复)
select if(A like%B%’,1,0) from table  #逻辑判断

4.想统计各个城市中有多少数据分析职位,其中,电商领域的职位有多少,在其中的占比

select city,
count(distinct Id),
count(distinct(if(industryField like%电子商务%’,Id,null)))
from table
group by city  #占比,count函数对0,1都计数,因此用null

 

 

 第一列数字是职位总数,第二列是电商领域的职位数,相除就是占比

5.想找出各个城市,数据分析师岗位数量在500以上的城市有哪些

第一种,是使用having语句,它对聚合后的数据结果进行过滤。

WHERE 子句对被选择的列施加条件,而 HAVING 子句则对 GROUP BY 子句所产生的组施加条件。

在 SELECT 查询中,HAVING 子句必须紧随 GROUP BY 子句,并出现在 ORDER BY 子句(如果有的话)之前。

select city,count(distinct Id) from table
group by city 
having count(distinct Id) >= 500

 

 

 注意,筛选出"城市"列的内容出现次数大于或等于 2 的所有记录,此时就要结合嵌套子查询

SELECT * FROM Customers
WHERE 城市 IN (
SELECT 城市 FROM Customers
GROUP BY 城市
HAVING COUNT(1)>1
)

 

 

 

上面的代码用了一个子查询,主要是因为在SQL Server中GROUP BY分组后,在SELECT后面显示的列里面只能显示分组的列,比如我们这里对城市分组了,那么子查询里面就只能显示城市列,显示不了其他列

第二种,是利用嵌套子查询。
注意:
子查询不能使用 ORDER BY,不过主查询可以。在子查询中,GROUP BY 可以起到同 ORDER BY 相同的作用。
返回多行数据的子查询只能同多值操作符一起使用,比如 IN 操作符。
通常情况下子查询都与 SELECT 语句一起使用;但还可以用在 INSERT 语句中。INSERT 语句可以将子查询返回的数据插入到其他表中。子查询中选取的数据可以被任何字符、日期或者数值函数所修饰;也可以用在 UPDATE 语句中。当子查询同 UPDATE 一起使用的时候,既可以更新单个列,也可更新多个列;还可以同 DELETE 语句一起使用。

select * from (
    select city,count(distinct Id) as counts from table
    group by city ) as table1
where counts >= 500

6.排序

select * from table
group by A  
order by B  #将数据升序
select * from table
group by A  
order by B desc  #将数据降序

多列排序,按 "省份" 升序排列,并按 "姓名" 列降序排列

ORDER BY 省份 ASC, 姓名 DESC;

7.时间

GETDATE()函数用于返回当前数据库系统的日期和时间
SELECT GETDATE()
GETUTCDATE()函数返回当前UTC(世界标准时间)日期值,即格林尼治时间(GMT) 
SELECT GETUTCDATE()
YEAR()函数以int数据类型的格式返回特定日期的年度信息
SELECT YEAR(GETDATE())
select now()  #当前的系统时间,精确到秒
select date(now())   #当前日期

week函数获得当前第几周,month函数获得当前第几个月。其余还包括,quarter,year,day,hour,minute

时间加减法

select date_add(date(now()) ,interval 1 day)

改变1为负数,达到减法的目的

求两个时间的间隔

datediff(date1,date2)或者timediff(time1,time2)

 

 

 

8.通过salary计算数据分析师的工资

首先利用locate函数查找第一个k所在的位置。

select locate(“k”,salary),salary from table

 

 

 然后使用left函数截取薪水的下限。

select left(salary,locate(“k”,salary)-1),salary from DataAnalyst

 

 

 为了获得薪水的上限,要用substr函数,或者mid,两者等价。

substr(字符串,从哪里开始截,截取的长度)

薪水上限的开始位置是「-」位置往后推一位。截取长度是整个字符串减去「-」所在位置,刚好是后半段我们需要的内容,不过这个内容是包含「K」的,所以最后结果还得再减去1。

select left(salary,locate("k",salary)-1) as bottomsalary,
       substr(salary,locate("-",salary)+1,length(salary)-locate("-",salary)-1) as topsalary,
       salary from table
where salary not like "%以上%"

然后计算不同城市不同工作年限的平均薪资。

select city,workyear,avg((bottomsalary+topsalary)/2) as avgsalary from(
      select left(salary,locate("k",salary)-1) as bottomsalary,
            substr(salary,locate("-",salary)+1,length(salary)-locate("-",salary)-1) as topsalary,
            city,Id,workyear from table
       where salary not like "%以上%") as table1
group by city,workyear
order by city,avgsalary

 

 

 

9.查询出哪家公司招聘的岗位数最多

查询出O2O、电子商务、互联网金融这三个行业,哪个行业的平均薪资最高;
查询出各城市的最高薪水Top3是哪家公司哪个岗位。

10.JOIN

 

 

 

inner join等价于join
left join返回A表所有的行,B表中所有数据对应横向放在A表后面,若A表中数据行较多,那么对于B表中的字段若在A表中不存在对应数据行,则用 NULL来填充。
full join只要A表和B表中有一个关键字存在匹配,则返回两个表的所有行,没有匹配的地方自动用NULL填充。
A Full Join B = A Left Join B + A Right Join B – A Inner Join B

自结合

select a.customer_id,a.rental_date,a.return_date,b.first_name,b.last_name 
from rental a inner join customer b
on  a.customer_id=b.customer_id;

等价于
select a.customer_id,a.rental_date,a.return_date,b.first_name,b.last_name 
from rental a,customer b
where  a.customer_id=b.customer_id;

11.仅在指定的列中插入数据

INSERT INTO Customers (姓名, 城市, 省份)
VALUES ('武松', '邢台', '河北省');

 

 

 

12.UPDATE 语句用于更新表中的现有记录

UPDATE table_name 
SET column1 = value1, column2 = value2, ... 
WHERE condition;

WHERE子句指定哪些记录需要更新。如果省略WHERE子句,所有记录都将更新

举例:

UPDATE Customers
SET 姓名= '鲁智深',城市= '平凉',省份='甘肃省'
WHERE 姓名 ='张三';

 

 

 

13.DELETE语句用于删除表中现有记录

DELETE FROM table_name WHERE condition;

 

 

 

14.LIKE运算符

 

 

 

15.UNION运算符用于组合两个或更多SELECT语句的结果集

UNION使用前提:UNION中的每个SELECT语句必须具有相同的列数
这些列也必须具有相似的数据类型,每个SELECT语句中的列也必须以相同的顺序排列

SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

UNION 运算符选择一个不同的值,即不允许重复值

SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;

允许重复值

16.ALTER TABLE 语句用于在已有的表中添加、修改或删除列

若要向表中添加列,请使用以下语法:
ALTER TABLE table_name
ADD column_name datatype
若要删除表中的列,请使用以下语法:
ALTER TABLE table_name
DROP COLUMN column_name
若要更改表中列的数据类型,请使用以下语法:
ALTER TABLE table_name
CHANGE COLUMN column_name datatype

17.约束

约束是作用于数据表中列上的规则,用于限制表中数据的类型。约束的存在保证了数据库中数据的精确性和可靠性。

约束有列级和表级之分,列级约束作用于单一的列,而表级约束作用于整张数据表。

NOT NULL 约束:保证列中数据不能有 NULLDEFAULT 约束:提供该列数据未指定时所采用的默认值
UNIQUE 约束:保证列中的所有数据各不相同
主键约束:唯一标识数据表中的行/记录
外键约束:唯一标识其他表中的一条行/记录
CHECK 约束:此约束保证列中的所有值满足某一条件
索引:用于在数据库中快速创建或检索数据

约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。

创建约束

CREATE TABLE table_name 
( 
column_name1 data_type(size) constraint_name, 
column_name2 data_type(size) constraint_name, 
column_name3 data_type(size) constraint_name, 
.... 
)

删除约束

ALTER TABLE EMPLOYEES DROP CONSTRAINT EMPLOYEES_PK;

18.索引

索引是一种特殊的查询表,可以被数据库搜索引擎用来加速数据的检索。简单说来,索引就是指向表中数据的指针。数据库的索引同书籍后面的索引非常相像。

索引能够提高 SELECT 查询和 WHERE 子句的速度,但是却降低了包含 UPDATE 语句或 INSERT 语句的数据输入过程的速度。索引的创建与删除不会对表中的数据产生影响。

CREATE INDEX index_name ON table_name;

单列索引
单列索引基于单一的字段创建

CREATE INDEX index_name ON 
table_name (column_name);

唯一索引
唯一索引不止用于提升查询性能,还用于保证数据完整性。唯一索引不允许向表中插入任何重复值

CREATE UNIQUE INDEX index_name ON
table_name (column_name);

聚簇索引
聚簇索引在表中两个或更多的列的基础上建立

CREATE INDEX index_name ON 
table_name (column1, column2);

创建单列索引还是聚簇索引,要看每次查询中,哪些列在作为过滤条件的 WHERE 子句中最常出现。

如果只需要一列,那么就应当创建单列索引。如果作为过滤条件的 WHERE 子句用到了两个或者更多的列,那么聚簇索引就是最好的选择。

强制索引

 

SQLite中,使用 INDEXED BY 语句进行强制索引查询,可参考:

SELECT * FROM salaries 
INDEXED BY idx_emp_no 
WHERE emp_no = '10005'

MySQL中,使用 FORCE INDEX 语句进行强制索引查询,可参考:

SELECT * FROM salaries 
FORCE INDEX idx_emp_no 
WHERE emp_no = '10005'

19.事务

事务是在数据库上按照一定的逻辑顺序执行的任务序列,既可以由用户手动执行,也可以由某种数据库程序自动执行。

事务实际上就是对数据库的一个或者多个更改。当你在某张表上创建更新或者删除记录的时,你就已经在使用事务了。控制事务以保证数据完整性,并对数据库错误做出处理,对数据库来说非常重要。

事务的属性
事务具有以下四个标准属性,通常用缩略词 ACID 来表示:
原子性:保证任务中的所有操作都执行完毕;否则,事务会在出现错误时终止,并回滚之前所有操作到原始状态。
一致性:如果事务成功执行,则数据库的状态得到了进行了正确的转变。
隔离性:保证不同的事务相互独立、透明地执行。
持久性:即使出现系统故障,之前成功执行的事务的结果也会持久存在。

事务控制
有四个命令用于控制事务:
COMMIT:提交更改;
ROLLBACK:回滚更改;
SAVE:在事务内部创建一系列可以 ROLLBACK 的还原点;
SET TRANSACTION:命名事务;

20.锁机制

  1. 共享锁:由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写。
  2. 排它锁:由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁,典型是mysql事务中的
    锁的范围:
    行锁: 对某行记录加上锁
    表锁: 对整个表加上锁
    这样组合起来就有,行级共享锁,表级共享锁,行级排他锁,表级排他锁。
  1. 加锁与解锁
    LOCK TABLES tablename WRITE;
    LOCK TABLES tablename READ;
    Insert INTO assignment VALUES (1,7513,'0000-00-00',5),(1,7513,'2003-01-20',8.5);
    UNLOCK TABLES;

  2. 不同锁的优缺点及选择
    行级锁的优点及选择:
    1)在很多线程请求不同记录时减少冲突锁。
    2)事务回滚时减少改变数据。
    3)使长时间对单独的一行记录加锁成为可能。

行级锁的缺点:
1)比页级锁和表级锁消耗更多的内存。
2)当在大量表中使用时,比页级锁和表级锁更慢,因为他需要请求更多的所资源。
3)当需要频繁对大部分数据做 GROUP BY 操作或者需要频繁扫描整个表时,就明显的比其它锁更糟糕。
4)使用更高层的锁的话,就能更方便的支持各种不同的类型应用程序,因为这种锁的开销比行级锁小多了。
5)可以用应用程序级锁来代替行级锁,例如MySQL中的 GET_LOCK() 和 RELEASE_LOCK()。但它们是劝告锁(原文:These are advisory locks),因此只能用于安全可信的应用程序中。
6)对于 InnoDB 和 BDB 表,MySQL只有在指定用 LOCK TABLES 锁表时才使用表级锁。在这两种表中,建议最好不要使用 LOCK TABLES,因为 InnoDB 自动采用行级锁,BDB 用页级锁来保证事务的隔离。

表锁的优点及选择:
1)很多操作都是读表。
2)在严格条件的索引上读取和更新,当更新或者删除可以用单独的索引来读取得到时:UPDATE tbl_name SET column=value WHERE unique_key_col=key_value;DELETE FROM tbl_name WHERE unique_key_col=key_value;
3)SELECT 和 INSERT 语句并发的执行,但是只有很少的 UPDATE 和 DELETE 语句。
4)很多的扫描表和对全表的 GROUP BY 操作,但是没有任何写表。

表锁的缺点:
1)一个客户端提交了一个需要长时间运行的 SELECT 操作。
2)其他客户端对同一个表提交了 UPDATE 操作,这个客户端就要等到 SELECT 完成了才能开始执行。
3)其他客户端也对同一个表提交了 SELECT 请求。由于 UPDATE的优先级高于 SELECT,所以 SELECT 就会先等到 UPDATE 完成了之后才开始执行,它也在等待第一个 SELECT操作。

21.常用字符处理函数

ASCII(字符串)
返回字符串表达式中最左侧的ASCII代码值

SELECT ASCII('S'),ASCII('SQL')

 

 CHAR(字符)
将整数类型的ASCII值转换为对应的字符

SELECT CHAR(83)

 

 LEN(需要获取长度的字符串)

SELECT LEN('SQL学习之路')

 

 LEFT(需要被从左边截取的字符串,截取的长度)

SELECT LEFT('SQL学习之路',2)

 

 RIGHT(需要被从右边截取的字符串,截取的长度)

SELECT RIGHT('SQL学习之路',2)

 

 CHARINDEX(需要查找位置的子字符串,父字符串,从哪个位置开始找)
返回:被查找的子字符串在父字符串中的位置
从第一个位置查找‘SQL学习之路’中的‘路’字在哪个位置

SELECT CHARINDEX('','SQL学习之路',1)

 

 PATINDEX(%需要查找的子字符串%,父字符串)
返回指定表达式中模式第一次出现的开始位置,子字符串可使用通配符%,而上面的CHARINDEX则不可以

SELECT PATINDEX('%数据%','SQL数据库开发')

 

 数据前面有个通配符_,代表一个任意字符的意思

SELECT PATINDEX('%_数据%','SQL数据库开发')

 

 LTRIM(需要被清空的字符串)
返回:被清空左边空格的字符串

SELECT LTRIM('     SQL学习之路')

 

 

还有RTRIM(需要被清空右边的字符串)

STUFF(字符串,开始下标,截取长度,插入的字符串)
在一个字符串中,删除指定长度的字符,并在该位置插入一个新的字符串;

SELECT STUFF('ABCDEFG', 2, 3, 'SQL学习之路')

 

 REPLACE(指定字符串,需要被替换的字符串,替换为的字符串)
返回新字符串

SELECT REPLACE('SQL学习之路','学习','成长')

 

 REPLACE与TRANSLATE的区别
https://blog.csdn.net/u013361361/article/details/21126279

 

UPPER(需要转换为大写的字符串)
把传递给它的字符串转换为大写

SELECT UPPER('sql学习之路')

 

 

还有LOWER(需要转换为小写的字符串)

SUBSTRING(字符串,起始下标,长度)
提取字符串

SELECT SUBSTRING('SQL学习之路',4,4)

 

 REVERSE(需要逆向取值的字符串)
返回字符串值的逆向值

SELECT REVERSE('SQL学习之路')

 

 REPLICATE(需要重复的字符串 ,重复次数)
以指定的次数重复字符串值

SELECT REPLICATE('SQL',3)

 

 

 

 

 

 

 

 

 

 

22.数据库的性能优化方法有哪些?

主要有基于规则的优化(rules)、基于成本的优化(cost)
1)基于规则的优化
通常是基于表查询的优化,方法有:选择最有效率的表顺序,避免select *的出现,用TRUNCATE替代DELETE等
2)基于成本的优化
建立索引;
建立分区表;
视图、函数的适当使用;
返回更少数据(不必要的字段);
数据库的表越少越好,表的字段越少越好;
适当的冗余,增加计算列,提高数据库的运行效率;
存储过程,如果采用存储过程你可以将整个业务逻辑封装在存储过程里,然后在客户端直接调用存储过程处理,这样可以减少数据库交互的成本;

23.事务型数据库与分析型数据库的特征及二者区别?

事务型数据库主要是实时的,面向应用的数据库,响应及时性要求很高,只关注最近一段时间的数据。就是平时搭建的服务都叫事务型数据库。
分析型数据库主要是用于在大量数据中分析规律的,一般存储的数据时间跨度长,数据量大,对实时性要求不高,通过查询分析规律趋势,用于产品决策等,如数据仓库。

24.谓词EXISTS

EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
EXISTS 指定一个子查询,检测 行 的存在。

语法: EXISTS subquery
参数: subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。
结果类型: Boolean 如果子查询包含行,则返回 TRUE ,否则返回 FLASE 。

与集合成员资格运算符IN的区别
IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
①exists:存在,后面一般都是子查询,当子查询返回行数时,exists返回true。
select * from class where exists (select'x"form stu where stu.cid=class.cid)
当in和exists在查询效率上比较时,in查询的效率快于exists的查询效率
exists(xxxxx)后面的子查询被称做相关子查询, 他是不返回列表的值的.
只是返回一个ture或false的结果

其运行方式是先运行主查询一次 再去子查询里查询与其对应的结果 如果存在,返回ture则输出,反之返回false则不输出,再根据主查询中的每一行去子查询里去查询.

执行顺序如下:
首先执行一次外部查询
对于外部查询中的每一行分别执行一次子查询,而且每次执行子查询时都会引用外部查询中当前行的值。
使用子查询的结果来确定外部查询的结果集。

②in:包含
查询和所有女生年龄相同的男生
select * from stu where sex='男' and age in(select age from stu where sex='女')
in()后面的子查询 是返回结果集的,换句话说执行次序和exists()不一样.子查询先产生结果集,
然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出.

查询所有选修了1号课程的学生姓名

思路分析:
   本查询涉及Student和SC关系
   在Student中依次取每个元组的Sno值,用此值去检查SC关系
   若SC中存在这样的元组,其Sno值等于此Student.Sno值,并且其Cno= '1',则取此Student.Sname送入结果关系
   用嵌套查询
     SELECT Sname
     FROM Student
     WHERE EXISTS
                   (SELECT *
                    FROM SC
                    WHERE Sno=Student.Sno AND Cno= ' 1 '); 
   用连接运算
    SELECT Sname
    FROM Student, SC
    WHERE Student.Sno=SC.Sno AND SC.Cno= '1';

25.谓词any、all

这两个都是用于子查询的
any 是任意一个
all 是所有

 

any表示有任何一个满足就返回true,all表示全部都满足才返回true

select * from student where 班级=01and age > all (select age from student where 班级=02’); 
就是说,查询出01班中,年龄大于 02班所有人的同学 
相当于 
select * from student where 班级=01and age > (select max(age) from student where 班级=02’);

而 
select * from student where 班级=01and age > any (select age from student where 班级=02’); 
就是说,查询出01班中,年龄大于 02班任意一个 的 同学 
相当于 
select * from student where 班级=01and age > (select min(age) from student where 班级=02’);

查询其他系中比计算机科学某一学生年龄小的学生姓名和年龄

SELECT Sname,Sage
FROM    Student
WHERE Sage < ANY (SELECT  Sage
                                     FROM    Student
                                     WHERE Sdept= ' CS ')
           AND Sdept <> ‘CS ' ;     
等价于
SELECT Sname,Sage
FROM   Student
WHERE Sage < (SELECT MAX(Sage)
                            FROM Student
                            WHERE Sdept= ‘CS ')
           AND Sdept <> ' CS ’ ;

查询其他系中比计算机科学系所有学生年龄都小的学生姓名及年龄

用ALL谓词
    SELECT Sname,Sage
    FROM Student
    WHERE Sage < ALL
                           (SELECT Sage
                            FROM Student
                            WHERE Sdept= ' CS ')
           AND Sdept <> ' CS ’;
等价于
用聚集函数
        SELECT Sname,Sage
        FROM Student
        WHERE Sage < 
                               (SELECT MIN(Sage)
                                FROM Student
                                WHERE Sdept= ' CS ')
              AND Sdept <>' CS ’;

26.视图

视图正如其名字的含义一样,是另一种查看数据的入口。
常规视图本身并不存储实际的数据,而仅仅是由SELECT语句组成的查询定义的虚拟表 。
视图是一个虚拟的表,是一个表中的数据经过某种筛选后的显示方式,视图由一个预定义的查询select语句组成。
视图最多可以有 1024 列

视图的特点
视图中的数据并不属于视图本身,而是属于基本的表,对视图可以像表一样进行insert,update,delete操作。
视图不能被修改,表修改或者删除后应该删除视图再重建。
视图的数量没有限制,但是命名不能和视图以及表重复,具有唯一性。
视图可以被嵌套,一个视图中可以嵌套另一个视图。
视图不能索引,不能有相关联的触发器和默认值,sql server不能在视图后使用order by排序

视图的功能
1.简化用户操作
2.能以不同的角度观察同一个数据库
3.对重构数据库提供了逻辑独立性:
利用视图将需要的数据合并或者筛选,但是不影响原表的数据和结构
3.对机密数据提供安全保护:
可以建立不同的视图对用不同的用户,以达到安全的目的。

CREATE VIEW view_name AS
SELECT column1, column2.....
FROM table_name
WHERE [condition];

例:

 
CREATE VIEW actor_name_view(first_name_v,last_name_v) AS
SELECT first_name,last_name
FROM actor

27.触发器

何为触发器?在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。
常见的触发器有三种:分别应用于Insert , Update , Delete 事件。

CREATE TRIGGER trigger_name
 ON table_name
 [WITH ENCRYPTION]
  FOR | AFTER | INSTEAD OF [DELETE, INSERT, UPDATE]
 AS 
  T-SQL语句
GO
--with encryption 表示加密触发器定义的sql文本
--delete,insert,update指定触发器的类型</pre>

例:

 

 

1)如果我更改了学生的学号,我希望他的借书记录仍然与这个学生相关(也就是同时更改借书记录表的学号);

对于1,创建一个Update触发器: 

     Create Trigger truStudent 
       On Student                         --在Student表中创建触发器 
       for Update                          --为什么事件触发 
     As                                        --事件触发后所要做的事情 
       if Update(StudentID)            
       begin 

         Update BorrowRecord 
           Set StudentID=i.StudentID 
           From BorrowRecord br , Deleted   d ,Inserted i      --Deleted和Inserted临时表 
           Where br.StudentID=d.StudentID 

       end      

一个Update 的过程可以看作为:生成新的记录到Inserted表,复制旧的记录到Deleted表,然后删除Student记录并写入新纪录。

2)如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。

对于2,创建一个Delete触发器 
     Create trigger trdStudent 
       On Student 
       for Delete 
     As 
       Delete BorrowRecord 
         From BorrowRecord br , Delted d 
         Where br.StudentID=d.StudentID 

28.SQL优化问题

https://mp.weixin.qq.com/s/6gqDy8VsMWUSgvc8zhnB6Q

29.ifnull函数与coalesce()函数

1)ifnull
ifnull函数用于在表达式是NULL时,从另外一个表达式获得值,它可以用于大多数数据类型,但值与替代值必须是同一数据类型

IFNULL(expr1,expr2)
如果 expr1 不是 NULL,IFNULL() 返回 expr1,否则它返回 expr2。

2)coalesce函数用指定值代替NULL,其不同点在于,它可以接受一个数据集,一次检查其中的每一个值,知道发现一个非null值,如果没有找到非null值,它会返回一个值
①用途:
将空值替换成其他值
返回第一个非空值

②表达式:
COALESCE是一个函数, (expression_1, expression_2, ...,expression_n)依次参考各参数表达式,遇到非null值即停止并返回该值。如果所有的表达式都是空值,最终将返回一个空值。使用COALESCE在于大部分包含空值的表达式最终将返回空值。

30.instr函数

INSTR(C1,C2,I,J) 在一个字符串中搜索指定的字符,返回发现指定的字符的位置;
C1 被搜索的字符串
C2 希望搜索的字符串
I 搜索的开始位置,默认为1
J 出现的位置,默认为1
SQL> select instr("abcde",'b');

结果是2,即在字符串“abcde”里面,字符串“b”出现在第2个位置。如果没有找到,则返回0

31.decode函数

decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)

  该函数的含义如下:
  IF 条件=值1 THEN
  RETURN(翻译值1)
  ELSIF 条件=值2 THEN
  RETURN(翻译值2)
  ......
  ELSIF 条件=值n THEN
  RETURN(翻译值n)
  ELSE
  RETURN(缺省值)
  END IF

 

 
posted @ 2019-10-12 16:59  农名工进城  阅读(263)  评论(0编辑  收藏  举报