这篇文章用于记录各种常用的入门级SQL语句,方便各位快速学会数据库的基础操作或入门。
一天晚上,易境做完任务后,正准备偷偷溜走时,在门口直接被老板一把抓住!!!
老板:“有个数据库要你改改,明天晚上按照要求改完给我。”
我(瑟瑟发抖.jpg):“可是老板,我是前端啊?”
老板:“你不是程序员吗?啥前后端,你能不能干???”
我(蔫了.jpg):“我.....”
没等说完,老板就塞了一份文档给我,然后就大步流星的.....自己先溜走了。
......没办法,人类为什么要上班啊.....
--
--
--
那么先找个地方练一下SQL语句吧.....不然万一不小心删库了.....
于是就找到了一个在线练习SQL语句的网站!推荐一下(不是打广告!!!)
用注册也不用魔法上网,啥也不用下载直接就能在上面练习!
进入之后网站长这个样子:
好的,那么这边提供一个数据库文件,这个文件是b站up PAPAYA电脑教室 开放的!用于sql语句的初步练习,链接如下:
把其中的文件下载下来后,点击网站中的这个按钮,之后选中下载好的csv后缀文件(如果下载后的文件不是csv后缀,改成csv后缀便好):
导入成功后页面变成这样:
好的,下面开始正式学习与分享各种sql语句~
1.注释
注释,一个无论是初出茅庐的萌新,还是久经沙场的大佬,对这个东西都是又爱又恨;每天都在“我不想写注释~”和“为啥你代码没有注释?”之间徘徊,注释?那不是别人的活嘛(别打了别打了!)。为了以后编码不被别人暴揍,先讲一下这个
(话说能看这篇文章的应该都知道注释是干啥的吧?在此不多赘述了)
多行注释写法:
/*
我
是
注
释
*/
单行注释:
--我是注释
而在网站页面中的两行英文意思为:
- Your CSV file has been imported into students table.(你的csv数据表成功导入)
- You can run this SQL query to make all CSV records available for charting.(你可以用sql语句来操作它)
2.查询数据的那些事
页面中的注释部分讲解完了,那么剩下的那一行是什么意思呢?
正常查找
SELECT * FROM "students";
其中,
SELECT英文里是“选取”的意思,
*在这里代表全部,
FROM “students” 代表从students表中查询
所以这一行语句的意思是
从students表中查询全部数据
那么,按这个说法,当我们运行时,就能够出现数据库中的所有内容!
现在运行一下吧,点击运行:
真的出现了表中的数据!
选择指定列的查找
好的,但是实际应用中,我们有时不用数据库直接传回所有的数据,只需要数据库传回指定列的内容(这个列的专业术语叫“属性”)
遇到这种情况,你就把语句里的 * 换成你想要搜索的属性名字便可~
比如替换后的下面的语句:
SELECT 姓名,班級 FROM "students";
(注意两个属性之间用英文的逗号","分割!!!)
运行语句,可见之传出了指定属性的数据
显示指定行数的查找
但是如果在几十万的数据库中,查询之后数据全都传回来了,这也会导致查找困难。所以你可以这么写来限制数据库返回的数据数量:
SELECT 姓名,班級 FROM "students" LIMIT 2;
LIMIT英文含义为“限制”,在这里,他就可以起到限制传回的数据量;
上面的语句意义为“从students表中查询属性为‘姓名’‘班级’的数据,并只需传回两行”
显示如下,数据库就只返回两行数据了:
看“下一页”的查询结果
上面的代码中,数据库只返回了第一行和第二行数据,但是我要是想看第三行和第四行数据怎么办?
那么就这样写:
SELECT 姓名,班級 FROM "students" LIMIT 2 OFFSET 2;
OFFSET此处表示“跳过”,那么这行代码的含义就是“从students表中查询属性为‘姓名’‘班级’的数据,并只需传回两行,传回的数据跳过前两行”
那么,运行后就应该是第三行和第四行的数据:
同理,你要是想跳过4行数据,你就把OFFSET后面的数字改为“4”即可。
筛选内容后的查询
如果我想要查看某个班级成员的全部成绩,应该怎么办呢?
WHERE 在此处起到筛选输出数据的功能
比如我只想看“1 年 1 班” 学生的成绩,就这么写:
SELECT 姓名,班級,成績 FROM "students"
WHERE 班級 = '1 年 1 班';
看,就输出了1年1班学生的成绩:
从这里可以看到,WHERE语法就是
--WHERE 属性 筛选符号 (如'=','<>') '筛选名称'
注意,上面的筛选符号"<>"是不等号,那我们来用一下不等号,如果是其他的编程语言,此时应该会输出除了1年1班以外的班级,看看会发生什么:
SELECT 姓名,班級,成績 FROM "students"
WHERE 班級 <> '1 年 1 班';
输出,可以看到确实输出了除了1年1班以外的班级:
但是这时老板突然闪现到背后:“为啥这个输出出来的数据如此杂乱!2班同学和3班同学的输出放在一起才好看!!!”
(我艹你啥时候过来的)
于是被骂了一顿后,易境就灰溜溜去改了。
排序,各种各样的排序
问题来了,怎么改?注意到了有一点,其他的很多编程语言中都可以用排序来做到类似的数据放在一起的效果,那么sql应该也可以...吧?
事实证明确实如此,sql中支持对输出数据进行排序,用的是“ORDER BY”
就像这样写:
SELECT 姓名,班級,成績 FROM "students"
WHERE 班級 <> '1 年 1 班'
ORDER BY 班級;
上面的排序就表示“针对班级进行从小到大的排序”。原理是系统会自动对比每个字符的大小,最后发现2 > 3 ,所以就把所有2班的输出放在3班的前面,让数据输出更规范了。
效果:
自然的,你可以进行其他的排序,比如在数据输出规范的情况下,让成绩从小到大排序:
SELECT 姓名,班級,成績 FROM "students"
WHERE 班級 <> '1 年 1 班'
ORDER BY 班級,成績 ;
上面的排序就表示,“现针对班级进行数据排序,再针对成绩进行数据排序”。而在sql中,数据排序的结果默认是从小到大的,如图:
如果你想要输出结果从大到小,在ORDER BY末尾加上“DESC”(降序输出的意思,并不是真的从代码中让系统从大到小排序了,而是修改了数据的输出顺序):
SELECT 姓名,班級,成績 FROM "students"
WHERE 班級 <> '1 年 1 班'
ORDER BY 班級,成績 DESC ;
就会发现输出变成从大到小了:
模糊查询
人们在查询数据时,偶尔会遇到名字想不完整的情况,比如有时会遇到“马什么梅?”,“什么冬梅?”的问题,而在sql中支持类似的模糊查询,即使不知道全部的信息也可以完成查询,十分方便!
比如我想要查询名字是“两个字,姓氏为‘張’,名字不知道”
我们就可以这样写:
SELECT 姓名,班級,成績
FROM "students"
WHERE 姓名 LIKE '張_';
是不是很像正常查询数据的样子?只要把=改成LIKE,把未知的字符写成'_',就可以模糊查询:
查询中的其他重要字符
AND
SQL中,支持用AND表示类似其他语言中的“与”条件(AND类似c语言中的'&&')
比如我想要查成绩在80到90之间的人,逻辑上可以表示“成绩大于80 和 成绩小于90”
就可以这样写:
SELECT 姓名,班級,成績
FROM "students"
WHERE 成績 >80 AND 成績 < 90;
就会输出80分到90分之间的人:
BETWEEN
上面的代码可以使用between and 语法来达到相同的效果
SELECT 姓名,班級,成績
FROM "students"
WHERE 成績 BETWEEN 80 AND 90 ;--筛选成绩位于80到90间的数据
输出结果与上面的图相同
结合使用
和其他编程语言一样,AND可以结合使用以达到其他效果
比如此时老板不但让我输出成绩位于80与90间的人,还要求这些人是1年2班的
那么就这样写
SELECT 姓名,班級,成績
FROM "students"
WHERE 成績 BETWEEN 80 AND 90
AND 班級 = '1 年 2 班' ;--表示筛选成绩80到90间的一年二班学生,另外此处分行是为了代码好辨认
输出后就是区分后的结果啦:
OR 与 括号的妙用
OR 在SQL表示“条件或”,就等同于c语言里的“||”
如果想要输出一年二班和一年一班中、成绩80到90分之间的人呢?
聪明的你也许会这样写:
SELECT 姓名,班級,成績
FROM "students"
WHERE 成績 BETWEEN 80 AND 90
AND 班級 = '1 年 2 班' OR 班級 = '1 年 1 班';--另外此处分行是为了代码好辨认
这样写看似正确,但实际上有个bug,我们来运行一下:
发现输出中有80-90分以外的东西混进来了!为什么呢?
原来在sql中,AND 执行优先级高于 OR ,导致SQL先处理了
WHERE 成績 BETWEEN 80 AND 90 AND 班級 = '1 年 2 班'
也就是先筛选了一年2班中成绩80到90间的
然后才执行
OR 班級 = '1 年 1 班';
之后才执行“筛选出1年1班的人”
这是不对的,此时我们可以像四则运算一样用括号更改优先级,你可以先想一下怎么写,
公布答案,正确写法:
SELECT 姓名,班級,成績
FROM "students"
WHERE 成績 BETWEEN 80 AND 90 AND (班級 = '1 年 2 班' OR 班級 = '1 年 1 班');
这就让sql先处理“筛选一年二班与一年一班的学生”之后在从中找出80-90分的学生:
我们可以用IN表示出相同的效果,像这样写:
SELECT 姓名,班級,成績
FROM "students"
WHERE 成績 BETWEEN 80 AND 90 AND (班級 IN ('1 年 2 班' , '1 年 1 班'));
输出的结果和上面是一样的
编码规范
一般来讲,别人会建议把“单词”分行写,然后语句的最后加入‘;’结尾,像这样:
SELECT 姓名,班級
FROM "students"
LIMIT 2
OFFSET 2;
这样写不会改变代码原意,但他们说这样写更好看,更易于维护 (真的吗?)
3.常见函数
sql和excel表格中的函数类似,也有可以求平均数,求和之类的函数,在此一并写下:
SELECT AVG(成績),SUM(成績),MAX(成績),MIN(成績),COUNT(成績)
FROM "students"
输出:
AVG--求一个属性中的平均数;
SUM--求一个属性中的和
MAX--求一个属性中的最大值
MIN--求一个属性中的最小值
COUNT--求一个属性中的元素数量
修改属性名
如果觉得输出的列的名称不够直观,你可以使用AS来修改输出的属性名
比如我想修改AVG(成绩)为平均分:
SELECT AVG(成績) AS 平均分 ,SUM(成績),MAX(成績),MIN(成績),COUNT(成績)
FROM "students"
输出效果,可以看出属性名称被修改了:
保留几位小数
如果想让类似平均分的小数保留固定的小数位数,可以使用ROUND,就像这样:
SELECT ROUND( AVG(成績) , 2 ) AS 平均分
FROM "students"
可以看到,ROUND语法格式为ROUND(小数,想保留的小数位数)
输出,可以看到平均分被保留了2位小数:
分组
这个功能经常和ROUND在一起使用,如果你想要分别查看每个班自己的平均分,就可以这样写:
SELECT 班級,ROUND( AVG(成績) , 2 ) AS 平均分
FROM "students"
GROUP BY 班級;
就可以输出每个班级的平均分,就像这样:
注意:如果想对分组后的数据作条件筛选,不要用WHERE,应该用HAVING!!!
比如你想要列出三个班中平均分大于80分的班级,就应该这样写:
SELECT 班級,ROUND(AVG(成績)) AS 成績平均
FROM students
GROUP BY 班級
HAVING 成績平均 >= 80 ;
效果:
4.sql关键字执行顺序
这是萌新最容易出bug的点,sql中存在着语句之间的执行顺序,错误的顺序可能会导致结果出错,所以一定要重点关注
执行顺序(优先级从高到低):
SELECT (选取)
FROM(来源)
WHERE(条件)
GROUP BY (分组展示)
HAVING (条件)
ORDER BY (顺序)
LIMIT (展示条数)
如果顺序错误,极有可能出现bug!!!!!!
举个例子,如果想要在列出平均分大于80分的班级后,还想要让这些数据从小到大(之前讲过的,用DESC倒序排列,记得吗?),就应该这样写:
SELECT 班級,ROUND(AVG(成績)) AS 成績平均
FROM students
GROUP BY 班級
HAVING 成績平均 >= 80 ;
ORDER BY 成績平均 DESC;
演示效果:
ORDER在 GROUP BY后面,如果放在前面,就会出现bug导致无法运行,像这样就是错的:
--反面教材演示!!!
SELECT 班級,ROUND(AVG(成績)) AS 成績平均
FROM students
GROUP BY 班級
ORDER BY 成績平均 DESC
HAVING 成績平均 >= 80 ;
自然就会出现报错:
5.各种计数
COUNT在SQL中是很常用的计数函数,默认状态下会自动忽略属性中空白的存储格,比如我们这里想查看社团数量,就这样写:
SELECT COUNT(社團)
FROM students;
效果就会显示忽略空白存储格后的社团数量:
COUNT经常和DISTINCT关键字使用以实现去重的效果,DISTINCT表示“去除重复的数据”,
比如现在我想要社团去重后的数量,看看真正有多少社团:
SELECT COUNT(DISTINCT 社團)
FROM students
就能得到去重后的结果了:
6.建表,插入数据,更新数据,删除数据
建表
这一块写如何用SQL建立一个表格
我们来建立一个关于社团的表格吧!
建表的格式为:
CREATE TABLE 表格名 (
属性名 属性类型 .
);
看着是不是很简单,如果想要建一个社团表,就像这样写:
CREATE TABLE clubs (
社团编号 INT ,--属性名为社团编号,这个属性存储的数据类型限制为INT
社团名称 VARCHAR(15)--属性名为社团名称,这个属性存储的数据类型为char字符型,字符大小最多为15
);
但是就像每个人类有自己唯一的身份证号一样,一个表中也应该指定一个属作为类似的身份证号,这个身份证号应该是唯一的(同一个表中不能有重复的),且不能为空的,这个身份证号被人们叫做“主键”PRIMARY KEY:
在这里我们指定社团编号为主键:
CREATE TABLE clubs (
社团编号 INT PRIMARY KEY,
社团名称 VARCHAR(15)
);
运行后发现创建成功:
插入数据
插入数据的格式为:
INSERT INTO 插入的表名 (主键名,插入的属性名)
VALUES (主键,'属性名');
比如我想插入几条数据在clubs中,就是:
INSERT INTO clubs (社团编号,社团名称)
VALUES (1,'计算机社'),(2,'文学社'),(3,'摸鱼社'),(4,NULL);
SELECT * FROM clubs;--这一行用来在插入成功后查看clubs中的数据是否插入成功,即使没有这一行也无所谓
如果报错,可以丢给AI,大概率是某个地方多打了一个空格
效果:
更新数据
更新数据的格式为:
UPDATE 更新的数据所在的表名称
SET 属性名称 = 更新后的数据名/数字
WHERE 主键名 = 4;
比如现在想要在主键为4的那一行的社团名称从NULL改为 歪比八卜 ,就这样写:
UPDATE clubs
SET 社团名称 = '歪比八卜'
WHERE 社团编号 = 4;--一定要用WHERE指定更新的主键!不然会导致所有数据变为 “歪比八卜”
SELECT * FROM clubs;--这一行用来在更新成功后查看clubs中的数据是否更新成功,即使没有这一行也无所谓
效果:
删除数据
和更新数据的操作类似,删除数据的格式为:
DELETE
FROM 要删除数据所属的表格名称
WHERE 要删除的数据的属性名的主键 = 主键名;
比如这里要删除歪比八卜:
DELETE
FROM clubs
WHERE 社团编号 = 4;
SELECT * FROM clubs;--这一行用来在删除成功后查看clubs中的数据是否删除成功,即使没有这一行也无所谓
效果:
今天的sql基础先写到这里了,这边要和老板对线去了QAQ