SQL语法整理

Posted 念奕玥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL语法整理相关的知识,希望对你有一定的参考价值。

参考:SQL查询语句大全

SQL基本语法入门

1、SQL执行顺序

第一步:执行FROM ----要先确定从哪个表中取数据
第二步:WHERE条件过滤-----过滤不需要的数据之后,再去操作符合条件的数据
第三步:GROUP BY 分组------ 数组可以分组的话先分组,然后再去select
第四步:使用聚合函数进行计算
第五步:HAVING条件过滤------计算之后筛选
第六步:执行ORDER BY排序-------数据都过滤、分组、挑选完成后,再执行排序。

2、库的操作(建库,删库)

-- 创建新数据库 
CREATE DATABASE 数据库名; 
-- 删除数据库 
DROP DATABASE 数据库名;

2.1 DROP、TRUNCATE和DELETE区别

删除的区别:drop直接删掉; truncate删除表中数据,再插入时自增长id又从1开始 ;delete删除表中数据,可以加where字句。
TRUNCATE和DELETE区别
日志:TRUNCATE不记录日志,DELETE记录日志,所以TRUNCATE要快于DELETE; 但是一旦用TRUNCATE进行删除就不能进行恢复,TRUNCATE是删除整张表的数据,不能加where条件。
(1)删除数据的过程: DELETE语句执行删除的过程:每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的,并且在删除的过程中不会激活与表有关的删除触发器,执行速度快。
(2)表和索引所占空间: 当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。
(3)删除效果(范围):drop > truncate > delete
(4)应用范围。TRUNCATE 只能对TABLE;DELETE可以是table和view(视图)
(5) TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)。
(6) truncate与不带where的delete :只删除数据,而不删除表的结构(定义);drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。
(7)是否回滚delete语句为DML(data maintain Language),这个操作会被放到 rollback segment中,事务提交后才生效。如果有相应的 tigger,执行的时候将被触发。truncate、drop是DLL(data define language),操作立即生效,原数据不放到 rollback segment中,不能回滚。
(8)**在没有备份情况下,谨慎使用 drop 与 truncate。**要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。要删除表用drop; 若想保留表而将表中数据删除,如果与事务无关,用truncate即可。如果和事务有关,或想触发trigger, 还是用delete。
(11) TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。
(12)对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。

3、增删改查

3.1 增

先建一张表:

CREATE TABLE t_user(
    id INT PRIMARY KEY AUTO_INCREMENT, -- 编号,设为主键(不重复,不为空),自增
    userName VARCHAR(20) NOT NULL DEFAULT '',-- 用户名 
    birthday DATE NOT NULL,-- 生日 
    tel CHAR(11) NOT NULL,-- 电话,char类型
    sex ENUM('男','女'),-- 枚举类型,该列的值只能取男和女 
    money INT -- 账户余额 
);

向表中添加数据INSERT INTO 表名(表头1,表头2) values(值1,值2);
如果列名和列的值不写,如果数据库设计时存在默认值,则添加默认值,否则默认添加为空(null)

INSERT INTO t_user(userName,birthday,tel,sex,money) 
VALUES ('张无忌','1980-05-09','13948577789','男',2000); 
 
INSERT INTO t_user(userName,,brthday,tel,sex) 
VALUES('张勇','1998-01-01','13112341234','男');

3.4 查

最简单的:
查询表中所有数据:select * from 表名
*表示显示所有的列,也可以指定显示列的列表,中间用","分割。
例如(显示姓名和工资列)sql select userName,money from t_user

3.4.1 聚合函数

使用格式:select 聚合函数 from 表名

总数量count(*),表示计算总行数,括号中写星与列名,结果相同
例:查询学生总数
select count(*) from Student 或 select count(s_id) from Student

最大值 max(列名):求此列的最大值
最小值 min(列名):求此列的最小值

求和 sum(列名):求此列之和(注:sum运算符与数字类型连用)

平均值 avg(列) :表示求此列的平均值(注:avg运算符与数字类型连用)
函数round(x,d) 四舍五入取值;
查询各科目成绩大于80分的百分比:
SELECT subject,ROUND(AVG(score > 80),2) as score_avg FROM study_score GROUP BY subject;

top:取表中前多少的数据
例1.取出表中第几行数据(如第一行)
select top 1 * from Student
例2.取出表中百分之多少数据
select top 50 percent * from Student

3.4.2 where条件语句查询

优先级由高到低的顺序为:小括号,not,比较运算符,逻辑运算符
and比or先运算,如果同时出现并希望先算or,需要结合()使用

比较运算符:> ,<, =, >=, <=, !=(<>)

逻辑运输符:and,or,not
🌰:查询张三和李四的信息
SELECT * FROM t_student WHERE userName='张三' OR userName='李四';

模糊查询:like %(表示任意多个字符);like前面也可以加not
🌰:select count(t_id) from teacher where t_name like '李%';

范围查询:in(非连续);between and(连续)
🌰:查询两个不相邻的学号的学生
select * from Student where StudentID in('19100142001','19100142006')
🌰:查询两个学号之间的学生
select * from Student where StudentID Between 19100142001 and 19100142006

空判断:is null;is not null
例1.查询没有试卷的学生
select * from Student where PaperType is null
例2.查询有试卷的学生
select * from Student where PaperType is not null

3.4.3 分组函数group by

group by 与聚合函数配合使用:
查出各个学院参加考试的人数
select CollegeID, count(StudentID) from Student group by CollegeID
group by 与having配合使用,虽然having的作用跟where子句功能一样,但having只用在group by出现的时候。
select CollegeID from Student group by CollegeID having CollegeID>10

3.4.4 排序 order by

order by 列名 asc----升序(asc不写也是默认升序),order by 列名 desc----升序

3.4.5 其他

查询多条件+显示部分**(LIMIT)**
– 查询前5条价格在100-1000的酒类商品 (mysql语法)
SELECT * FROM product WHERE productType='酒类' AND price>=100 AND price<=1000 LIMIT 0,5;

查询去除重复的类名**(distinct)**
– 查询所有的性别,distinct 表示去除重复记录
SELECT DISTINCT sex FROM t_student

练习题摘要sql语句练习50题(Mysql版)

--建表
--学生表
CREATE TABLE `Student`(
	`s_id` VARCHAR(20),
	`s_name` VARCHAR(20) NOT NULL DEFAULT '',
	`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
	`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
	PRIMARY KEY(`s_id`)
);
--课程表
CREATE TABLE `Course`(
	`c_id`  VARCHAR(20),
	`c_name` VARCHAR(20) NOT NULL DEFAULT '',
	`t_id` VARCHAR(20) NOT NULL,
	PRIMARY KEY(`c_id`)
);
--教师表
CREATE TABLE `Teacher`(
	`t_id` VARCHAR(20),
	`t_name` VARCHAR(20) NOT NULL DEFAULT '',
	PRIMARY KEY(`t_id`)
);
--成绩表
CREATE TABLE `Score`(
	`s_id` VARCHAR(20),
	`c_id`  VARCHAR(20),
	`s_score` INT(3),
	PRIMARY KEY(`s_id`,`c_id`)
);
-- 3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select b.s_id,b.s_name,ROUND(AVG(a.s_score),2) as avg_score from student b 
	join score a on b.s_id = a.s_id
	GROUP BY b.s_id,b.s_name HAVING avg_score >=60;
--4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩 (包括有成绩的和无成绩的)
select a.s_id,a.s_name,ROUND(AVG(b.s_score),2) as avg_score from student a 
left join score b on a.s_id = b.s_id 
GROUP BY a.s_id HAVING avg_score < 60 or avg_score is null; 
-- 5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
select a.s_id,a.s_name,count(b.c_id) as sum_course,sum(b.s_score) as sum_score from 
	student a 
	left join score b on a.s_id=b.s_id
	GROUP BY a.s_id,a.s_name;
			
			
-- 6、查询"李"姓老师的数量 
select count(t_id) from teacher where t_name like '李%';
-- 11、查询没有学全所有课程的同学的信息 
--@wendiepei的写法
select s.* from student s 
left join Score s1 on s1.s_id=s.s_id
group by s.s_id having count(s1.c_id)<(select count(*) from course)	
--@k1051785839的写法
select *
from student
where s_id not in(
select s_id from score t1  
group by s_id having count(*) =(select count(distinct c_id)  from course)) 
-- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩 
select a.s_id,a.s_name,ROUND(AVG(b.s_score)) from 
	student a 
	left join score b on a.s_id = b.s_id
	where a.s_id in(
			select s_id from score where s_score<60 GROUP BY  s_id having count(1)>=2)
	GROUP BY a.s_id,a.s_name

注:count(1) and count(字段)
两者的主要区别是:
(1) count(1) 会统计表中的所有的记录数, 包含字段为null 的记录。
(2) count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即 不统计字段为null 的记录。
转自:http://www.cnblogs.com/Dhouse/p/6734837.html

count(*) 和 count(1)和count(列名)区别

执行效果上 :
count(*)包括了所有的列,相当于行数,在统计结果的时候, 不会忽略列值为NULL
count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候, 不会忽略列值为NULL
count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数, 即某个字段值为NULL时,不统计。

执行效率上:
列名为主键,count(列名)会比count(1)快
列名不为主键,count(1)会比count(列名)快
如果表多个列并且没有主键,则 count(1) 的执行效率优于 count(
如果有主键,则 select count(主键)的执行效率是最优的
如果表只有一个字段,则 select count(
)最优。

-- 21、查询不同老师所教不同课程平均分从高到低显示 
select a.t_id,c.t_name,a.c_id,ROUND(avg(s_score),2) as avg_score from course a
		left join score b on a.c_id=b.c_id 
		left join teacher c on a.t_id=c.t_id
		GROUP BY a.c_id,a.t_id,c.t_name ORDER BY avg_score DESC;

以上是关于SQL语法整理的主要内容,如果未能解决你的问题,请参考以下文章

SQL语法整理

SQL语法整理

SQL语法整理

SQL语法整理

SQL基本语法整理(更新中)

SQL中部分语法整理