存放数据的仓库,用来按照特定的结构去组织和管理我们的数据,有数据库就可以更加方便的储存数据,英文名:DataBase,简称:DB.
数据库只是存储数据的一种手段,最终数据是存放在硬盘中的,只是存放的格式不同于文本文件。
Oracle: 收费的大型数据库,Oracle 公司的产品。Oracle 收购 SUN 公司,收购 MYSQL
DB2 : IBM 公司的数据库产品,收费的。常应用在银行系统中.
SQLServer: MicroSoft 公司收费的中型的数据车。C#、.net 等语言常使用。
SyBase:已经淡出历史舞台。提供了一个非常专业数据建模的工具 PowerDesigner。
SQLite:嵌入式的小型数据库,应用在手机端。
常用数据库:MYSQL,Oracle
在 web 应用中,使用的最多的就是 MySQL 数据库,原因如下:
1)开源、免费
2)功能足够强大,足以应付 web 应用开发(最高支持千万级别的并发访问)
windows安装MySQL很简单,可以参考阅读:https://blog.csdn.net/weixin_46758988/article/details/116368575
SQL全称Structured Query Language,意为结构化查询语言。说白了就是定义了操作所有关系型数据库的语言。每一种数据库的操作存在一定的差异,这个差异可以称为方言。
1.SQL语句可以单行或多行书写,以分号结尾。
-- 单行sql,查询数据库:
SHOW DATABASES;
# 多行sql:
SELECT *
FROM user;
2.SQL语句不区分大小写,但是关键字建议大写。
show databases;
SHOW databases;
3.注释:
-- 单行注释,横线后面空格不能省略
# 单行注释,空格可省略
/*多行注释*/
sql可以大致分四类:
1.DDL:操作数据库和表,如:
#操作数据库:
# 1.C(Create)创建
CREATE DATABASE db1;#创建一个db1数据库
CREATE DATABASE IF NOT EXISTS db2;#如果没有数据库db2就创建一个,否则不创建
CREATE DATABASE IF NOT EXISTS db3 CHARACTER SET gbk;#如果没有数据库db3就创建一个,否则不创建,创建时并指定字符编码为gbk
CREATE DATABASE db4 CHARACTER SET gbk;#创建一个数据库db4并指定字符编码集为gbk
# 2.R(Retrieve)查询
SHOW DATABASES;#查看数据
SHOW CREATE DATABASE mysql;#查数据库mysql的创建信息(创建字符集,创建语句)
# 3.U(Update)修改
ALTER DATABASE db3 CHARACTER SET utf8;#修改db3数据库字符编码集为utf-8,且记这里是utf8
# 4.D(Delete)删除
DROP DATABASE db2;#删除数据库db2,谨慎删除。
DROP DATABASE IF EXISTS db1;#如果数据库db1存在就删除
# 5.使用数据库
SELECT DATABASE();#查看当前正在使用的数据库
USE db1;#使用数据库db1
# 操作表:
# 1.新增
CREATE TABLE user_root(id INT, age INT); #给当前数据库新增一个user_root表,并给id和age两个字段,每个字段都需要指定类型
CREATE TABLE stu LIKE user_root; #复制user_root表并命名为stu(创建一个表,让它跟user_root表一样)
ALTER TABLE users ADD nickname VARCHAR(10); #给users表新增一列nickname,数据类型为可变字符varchar10个
# 2.查询
SHOW TABLES; # 查询当前使用的数据库中的所有表名称
SHOW TABLES FROM db1; # 查询数据库db1中所有的表
DESC user_tab; # 查询user_tab表结构
SHOW CREATE TABLE users; #查询users表的结构信息
# 3.删除
DROP TABLE stu; #删除stu表
DROP TABLE IF EXISTS user_root; #如果user_root表存在就删除
ALTER TABLE users DROP sex; #删除users表中的sex字段
# 4.修改
ALTER TABLE user_root RENAME TO users; #将user_root表名称修改为users;
ALTER TABLE users CHARACTER SET utf8; #修改users表的字符集为utf-8编码
ALTER TABLE users CHANGE gender sex INT; #修改users表中gender字段为sex字段并设置类型为int
ALTER TABLE users MODIFY sex VARCHAR(10); #修改users表中sex字段数据类型为varchar长度为10
DML:操作表中的数据,对表中数据进行增删改
# 1.新增数据
INSERT INTO users(id,age,nickname) VALUES (0,12,'苦海123'); #给users表中新增一条数据,全部字段给值(0,12,'苦海123')可以在后面继续用逗号隔开,如:(0,12,'苦海123'),(1,22,'123')表示一次插入多条数据
INSERT INTO users(id,nickname) VALUES (0,'苦海123'); #给users表中新增一条数据,只给id和nickname
INSERT INTO users VALUES (0,15,'苦海123');#给users表中新增一条数据,如果给所有字段都给值,那么前面的字段可以省略,直接给值
# 2.删除数据
DELETE FROM users;#删除表中所有数据,不推荐这种方式,因为很耗费性能,可以使用下面方式代替删除表中所有数据,如:
TRUNCATE TABLE users; #表示删除users表(表被删除了,数据也就没了),再创建一个一模一样的表
DELETE FROM users WHERE id = 1; #删除users表中id为1的数据
DELETE FROM users WHERE id IN (2,3);#删除users表中id存在后面括号中的值的数据
# 3.修改数据
UPDATE users SET age=15,nickname='kuhai123'; #修改users表中所有数据的age字段值为15,nickname值为kuhai123
UPDATE users SET age=18,nickname='kuhai123' WHERE id = 1;#修改users表中id为1的数据age字段值为18,nickname值为kuhai123
SQL:查询表中的数据
查询数据的语句结构:select 字段 from 表名 where 筛选条件 group bu 分组字段 having 分组之后的条件 order by 排序 limit 分页限定
基础查询:
SELECT * FROM student; #查询student表中所有字段对应的值
SELECT nams,age FROM student; #查询student表中nams和age字段对应的数据
SELECT DISTINCT address FROM student; #查询student表中address字段对应的数据并去重,这里的字段可以写多个,也可以写*,但是业务一般都是查一个字段,比如学生都来自哪里,DISTINCT表示去重
SELECT nams,math,english, math + english AS totalsco FROM student; #查询student表中的nams、math、math + english求和重命名为totalsco展示,AS可以用空格代替
SELECT nams,math + english FROM student; #查询nams字段、math + english求和并作为math + english字段展示所有数据
SELECT nams,math + IFNULL(english,0) FROM student;#求和的过程中可能会出现某个字段对应的值为null,此时可以使用IFNULL函数替换,这个函数第一个值表示字段,第二个值表示要替换的数值
SELECT * FROM student WHERE id <> 1;#查询student表中id不等于1的值,在sql中不等于用<>或!=表示
SELECT * FROM student WHERE id BETWEEN 2 AND 5;#查询student表中id在2和5之期间的数据,这里2和5都是可以取到的。
SELECT * FROM student WHERE id IN (1,2,5);#查询student表中id包含在1,2,5中的数据
SELECT * FROM student WHERE nams LIKE '%李%';#查询student中nams字段包含李的数据,这里是模糊查询,其中百分号表示模糊匹配,李字前后都写百分号表示包含李字都会被匹配到,如果只在李字后面写,则只会匹配李字开头的
SELE CT * FROM student WHERE nams LIKE '李%';#查询到student表中nams字段值李字开头的数据
SELECT * FROM student WHERE nams LIKE '%李';#匹配到student表中nams字段值李字结尾的所有数据
SELECT * FROM student WHERE nams LIKE '%华_';#匹配到student表中nams字段值华后面一个字的数据,其中下划线表示占1个字符
SELECT * FROM student WHERE nams LIKE '__';#匹配到student表中nams字段值为2个字符的数据,其中下划线表示占位,一个下划线表示占一个字符串的位置
SELECT * FROM student WHERE english IS NULL;#查询student表中englis字段值为null的数据,这里不能使用=做判断,也不可以使用!=判断不为null的数据,判断不是NULL用IS NOT NUll;
SELECT * FROM student WHERE math > 90 AND english > 90;#查询student表中math和english都大于90的数据,这里的AND也可以使用&&代替,如:
SELECT * FROM student WHERE math > 90 && english > 90;
SELECT * FROM student WHERE math > 90 OR english > 90;#查询student表中math大于90或english大于90的数据,这里的OR也可以使用||代替,如:
SELECT * FROM student WHERE math > 90 || english > 90;
SELECT * FROM student ORDER BY math DESC, english DESC;#按照math字段对数据进行降序排序,如果math相同则再按照english字段降序排序,排序通过order by实现,多个条件用逗号隔开
聚合函数:将一列数据作为一个整体,进行纵向计算=-
SELECT COUNT(nams) FROM student;#统计student表中有多少条数据,count用来计算一个表中有多少数据,括号里面一般给一个字段,也可以给星号,但是不推荐,因为查星号毫无意义,需要强调的是count统计的是非null的值,所有如果nams字段对应的值有为null的数据,那么统计的结果并不等于表中所有数据的数量
SELECT MAX(math) FROM student;#查询student表中math字段对应的最大值
SELECT MIN(math) FROM student;#查询student表中math字段对应的最小值
SELECT AVG(math) FROM student;#查询student表中math字段对应的平均值
SELECT SUM(math) FROM student;#查询student表中math字段对应的和
分组查询:将一类属性相同的数据分成一组然后做统计,分组查询的字段必须是分组字段或者聚合函数,其他值都没有任何意义
SELECT sex,AVG(math),SUM(math),COUNT(id) FROM student GROUP BY sex;#统计student表中math字段对应值按sex字段分类,各类数据的平均值,求和,个数统计(一句话:统计student表中男女的平均值,求和,个数统计)
SELECT sex,AVG(english),SUM(english),COUNT(id) FROM student WHERE english > 60 GROUP BY sex;#统计student表中english值大于60的数据,english字段对应值按sex字段分类,各类数据的平均值,求和,个数统计
SELECT sex,AVG(english),SUM(english),COUNT(id) FROM student WHERE english > 60 GROUP BY sex HAVING COUNT(id) >2;#查询student表中english大于60的数据并按sex分组统计平均值,求和,统计个数,并留下分组后个数大于2的分组,需要注意的是where在分组之前限定,而having在分组后进行限定,where后不能跟聚合函数,而having后可以跟聚合函数
SELECT * FROM student LIMIT 2,4;#表示越过2条查询4条数据,limit在mysql数据库中做分页查询,limit在SQLServer等数据库中不支持。
约束:
约束指对表中的数据进行限定,保证数据的正确性,有效性和完整性。约束可分为:主键约束primary key、非空约束not null、唯一约束unique、外键约束foreign key
#非空约束:值不能为null
CREATE TABLE stu(id INT, nams VARCHAR(20) NOT NULL); #创建一个stu表,对nams字段进行约束不能为null
ALTER TABLE stu MODIFY nams VARCHAR(20);#当一个表中字段被进行了约束,可以通过此方法对其重新定义字段约束(取消某种约束,唯一约束、主键约束、除外)
#唯一约束:不能有重复的值出现
ALTER TABLE stu MODIFY id INT UNIQUE;#对stu表中id字段进行唯一约束,使其字段的值不能重复,此约束和上面一样,在创建时也可以添加,任意约束都可以在创建和修改中添加,只需要用空格隔开,null值不划分到重复中,需要注意。
ALTER TABLE stu DROP INDEX id;#取消对stu表中id键的唯一约束,这里需要注意,主键不能通过修改取消。
#主键约束:值非空且唯一,主键一张表只能有一个,主键是表中唯一标识
ALTER TABLE stu MODIFY id INT PRIMARY KEY;#修改stu表中id为主键,在创建的时候也可以指定主键
ALTER TABLE stu DROP PRIMARY KEY; #删除主键
ALTER TABLE stu MODIFY id INT PRIMARY KEY AUTO_INCREMENT;#如果一个表中主键是唯一且是int类型,此时可以给主键加AUTO_INCREMENT,使其自动递增,当然可以在新增数据的时候可以指定值,指定值后,后面的值会在新的基础上增加1
ALTER TABLE stu MODIFY id INT;#删除自动递增
#外键约束:当两个表中有关联时,如:员工表中地址关联pid和地址表中id做关联时,如果员工表中有数据关联了地址表中数据,此时如果删除了地址表中被关联的数据就会用问题,此时可以借助外键约束来解决这个问题,当对某个表做外键约束时,关联的表中数据被删除时,如果这个关联的表中被删除的数据被有外键约束的表所引用,那么就提示不能被删除,也删除不掉,插入数据时,如果外键关联的数据不存在,则也添加不成,但是可以为NULL
CREATE TABLE emplay (id INT PRIMARY KEY AUTO_INCREMENT, nams VARCHAR(30),dep_id INT, CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id));#创建表时做外键约束,创建一个emplay表,CONSTRAINT表示限制,限制名定义称为了emp_dep_id,FOREIGN KEY表示外键为emplay表中的dep_id,REFERENCES表示引用为department表中的主键id,一般都是关联主键id。
ALTER TABLE emplay DROP FOREIGN KEY emp_dep_id; #删除emplay表的外键约束emp_dep_id
ALTER TABLE emplay ADD CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id);#给已经创建好的表添加外键约束
级联操作:当一个表有外键约束时,所引用的表中主键被修改时,此时所关联的数据就会发生错乱,当然这也是不能被修改的,如果想要修改,可以将表中关联id设置为NULL,之后在修改应用表中的id,然后将表中为NULL的值再改成新的id,当然这是比较麻烦且很笨的方式, 此时就可以借助级联操作。
如果想要清楚的看到表之间的关联关系,可以借助sqlyog中的架构设计器,可以清除得看到各表间用线连接的视图。
ALTER TABLE emplay ADD CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id) ON UPDATE CASCADE;#如果想要在修改了关联表中数据id,数据表中也同步自动更改,可以在创建表,外键时添加N UPDATE CASCADE,表示自动同步更新关联id
ALTER TABLE emplay ADD CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id) ON DELETE CASCADE;#删除级联
#级联比较耗性能,而且不便于操作,使用需谨慎。
DCL:授权,是否有权操作数据库,可以对用户进行管理,授权是指对某一个用户进行权限的处理,此时就要操作mysql这个数据库:
1.管理用户:
USE mysql;#切换到mysql数据库:
SELECT * FROM USER;#查询user表:
#2.创建用户:
CREATE USER 'kuhai123'@'localhost' IDENTIFIED BY '123456';#CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';这里创建的用户指定了主机,如果想要用户在任意的主机上面都能访问数据库,那么就要将localhost改为百分号%,表示通配符。
#3.删除用户:
DROP USER 'kuhai123'@'localhost';#DROP USER '用户名'@'主机名';
#4.修改用户信息:(修改用户的密码)
UPDATE USER SET PASSWORD = PASSWORD('sfs123') WHERE USER = 'kuhai123';#PASSWORD函数可以对密码进行加密处理,这里可能应版本问题导致报错,此时可以使用:
ALTER USER 'kuhai123'@'localhost' IDENTIFIED WITH mysql_native_password BY '123123123fgv';#其中kuhai123为用户名,localhost为主机名,123123123fgv为新密码。
修改root用户密码:
#修改root用户的密码:想要修改其他用户的密码,首先你得知道root用户的密码,但是有的时候难免密码是会被忘记的,此时可以使用以下方式修改密码:
#1.以管理员身份进入cmd终端:
net stop mysql #停止mysql服务
#2.使用无验证方式启动mysql服务:
mysqld --skip-grant-tables #终端继续执行此命令无验证开启mysql服务,这里可能开启失败,导致后面无法进入,此时可以尝试使用命令:mysqld --console --skip-grant-tables --shared-memory 无验证开启myslq服务
#3.当执行完第二步后,此时光标会卡在终端,此时新打开一个终端(无需管理员身份),继续输入命令:mysql -uroot -p,此时会提示输入密码,直接回车无需输入
#4.回车后提示进入mysql的提示语,此时表示进入mysql数据库成功。
#5.切换数据:use mysql;
#6.修改新密码:alter user root@localhost identified by '123456'; 此时可能提示修改失败,那么就需要先刷新一下权限:flush privileges; 然后在执行:alter user root@localhost identified by '123456'; 之后会提示修改成功的提示语。
#7.关闭两个终端即可。
#8.以管理员权限打开终端输入命令启动mysql服务:net start MySQL
#9.终端继续使用命令:mysql -uroot -p回车输入新的密码登录即可,SQLyog用新密码登录root账户可能会失败,失败请参考博客 https://blog.csdn.net/weixin_46758988/article/details/116368575 中MySQL数据可视化工具部分。
2.权限管理:
#1.查询权限:
SHOW GRANTS FOR 'kuhai123'@'localhost';#SHOW GRANTS FOR '用户名'@'主机名';其中权限分别表示:USAGE(表示只能登录,使用其它数据库是不可以的)、SELECT(查询权限)
#2.授予权限:
GRANT SELECT ON db3.account TO 'kuhai123'@'localhost';#给localhost主机下的kuhai123用户授予db3数据库中account表的查询权限,此时使用kuhai123登录数据库后,只能看到db3一个数据库,且此数据库中只能看到一个account表,且只能查看数据,不能对数据修改删除等操作
如果想要授权多个权限,则用逗号隔开即可,如:GRANT SELECT,DELETE,UPDATE,INSERT ON db3.account TO 'kuhai123'@'localhost';
给某个用户一次性授权所有数据库和所有表:GRANT ALL ON *.* TO 'kuhai'@'localhost';#如果刚开始已经单个授予某些表,那么使用此方式授权会有部分库和表授权不上的情况。新用户一次性授权可授权全部库和表。
#3.撤销权限:
REVOKE SELECT ON db3.account FROM 'kuhai123'@'localhost'; #撤销localhost主机下kuhai123用户表对db3数据库下account表的查询权限。
REVOKE ALL ON *.* FROM 'kuhai'@'localhost';#撤销localhost主机下kuahi用户的所有数据库和表的权限,注意,系统的部分数据库是无法撤销的如:information_schena
设计数据库时,需要遵循的一些规范被称为数据库设计的范式。它分为三类,分别是:
第一范式:每一列都是不可分割的原子数据项,意思就是说每个字段只能存一种数据,如:姓名和性别推荐存两个字段,不推荐存一个字段。
第二范式:在第一范式的基础上,非码属性必须完全依赖于候选码,分解理解:1.函数依赖:如果通过a属性的值可以确定唯一b的属性值,则称b依赖于a,如:通过学号可以确定姓名。2.完全函数依赖:如果a是一个属性组(学号+课程名称)确定一个属性值(该课程学分)3.部分函数依赖: 如果a是一个属性组,b属性的确定只需要依赖于a属性组中某个属性值即可,如:学号+课程名称属性组中,只通过学号就可以确定姓名 4.传递函数依赖:如果通过a属性或属性组的值可以确定唯一b属性的值,在通过b属性或属性组的值可以确定唯一c属性的值,则称c传递函数依赖于a如:学号依赖于系名,系名依赖于系主任 5.码:一张表中一个属性或属性组,被其他所有属性或属性组完全依赖,则称这个属性或属性组为该表的码,跟主键差不多一个意思。
第三范式:在第二范式的基础上,任何非主属性不依赖于其它非主属性(在第二范式的基础上消除传递依赖)
数据库的备份是防止数据异常导致数据丢失的情况出现。数据库备份的方式有两种:
1.通过命令行:mysqldump -u 用户名 -p 密码 > 保存的路径,如:
mysqldump -uroot -ptgbyhn123tgbyhn db1 > E://db1.sql
还原:登录数据库、创建数据库、使用数据库、执行文件(source 文件路径)
CREATE DATABASE db1;
USE db1;
souurce E://db1.sql;命令行执行
提示: 在备份时明文输入密码会提示Warning. Using a password on the command line interface can be insecure.告诉这样不安全,但是数据是备份成功的,如果需要改这个提示,win则需要修改my.cnf配置文件夹,Linux则需要新建一个密码和用户名的配置文件,具体百度即可。
2.通过图像化工具sqlyog:
备份:鼠标移动到某个数据库上右击–备份导出–备份数据库
还原:鼠标移动到数据库虚拟机上[email protected]右击 – 执行sql脚本(备份的sql脚本)
笛卡尔积:当查询一个表时有2条数据,当查询另一个表时有4条数据,当同时对这两个表进行查询时就会有8条数据(两表数据条数之积),然而连个表是有关系的,a表中有个关联键是关联了b表的主键,按道理查到的数据条数是a表条数数量才对,但是通过如下方式查询到的数据条数不对,且这种现象被称为笛卡尔积
SELECT * FROM emplay, department;
解决笛卡尔积现象:
多表查询可以解决笛卡尔积现象,多表查询分类:
内连接查询:
1.隐式内连接:使用where条件进行筛选无用数据:
SELECT * FROM emplay, department WHERE emplay.dep_id = department.id; #通过emplay表中的dep_id等于department表中的id可以选择出有用的数据,这里查询到的是emplay表中所有的数据,并查到emplay表中所有数据分别对应在department表中的字段
2.显式内连接:通过inner join on关键字进行数据的查询,inner可以省略:
SELECT * FROM emplay INNER JOIN department ON emplay.dep_id = department.id;# 查询emplay表中的数据,并加入department表中id等于emplay表中dep_id的数据
外连接查询:
1.左外连接:通过LEFT OUTER JOIN ON关键字查询数据,左外连接的含义是查询左边表的所有数据,以及它们的交际部分,on后面等号不满足的字段用null显式,此处OUTER可以省略掉。
SELECT * FROM emplay LEFT OUTER JOIN department ON emplay.dep_id = department.id;#查询到emplay表中所有的数据,即使emplay表中dep_id的值为null时,也是查询到所有,只是emplay表中dep_id为null的此条数据查询到后面department表中的数据都为null
2.右外连接:通过RIGHT OUTER JOIN ON关键字查询数据,右外连接的含义是查询右边表的所有数据,以及它们的交际部分,on后面等号不满足的字段用null显式,此处OUTER可以省略掉,和左外连接查询时相对的,方向换掉一样。
SELECT * FROM emplay RIGHT OUTER JOIN department ON emplay.dep_id = department.id;
子查询:查询中嵌套查询,称嵌套查询为子查询。
SELECT * FROM emplay WHERE salary = (SELECT MAX(salary) FROM emplay);#查询emplay表中salary最大值所对应的数据,按之前的方式一步是无法实现,可以分两步实现:1.查询最大值 2.使用where查询最大值所对应的数据,但是在很多时候分两条语句查询在后端处理时又比较繁琐,此时可以利用子查询,先查询括号中的值,然后通过where再筛选数据。
1.子查询的结果是单行单列的:子查询的结果作为前面条件查询的条件,判断符多为:>、<、=、>=、<=等。
SELECT * FROM emplay WHERE salary = (SELECT MAX(salary) FROM emplay);
2.子查询的结果是多行单列的:判断符号一般为in
SELECT * FROM emplay WHERE emplay.dep_id IN (SELECT id FROM department WHERE department.dep_name = '财务部' OR department.dep_name = '研发部');
3.子查询的结果是多行多列的:如果子查询到的结果是多行多列的,此时子查询到的结果可以作为一张虚拟表hightSalary
SELECT * FROM department, (SELECT * FROM emplay WHERE emplay.salary > 6000) hightSalary WHERE department.id = hightSalary.dep_id;
练习:
1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
SELECT e.id,e.ename,e.salary,j.jname,j.description FROM emp e JOIN job j ON e.job_id = j.id;
SELECT e.id,e.ename,e.salary,j.jname,j.description FROM emp e, job j WHERE e.job_id = j.id;
2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称部门位置
SELECT e.id,e.ename,e.salary,j.jname,j.description,d.dname,d.loc FROM emp e, job j, dept d WHERE e.job_id = j.id AND e.dept_id = d.id;
SELECT e.id,e.ename,e.salary,j.jname,j.description,d.dname,d.loc FROM emp e JOIN job j ON e.job_id = j.id JOIN dept d ON e.dept_id = d.id;
3.查询员工姓名,工资,工资等级
SELECT e.ename,e.salary, s.grade FROM salarygrade s, emp e WHERE e.salary >= s.losalary AND e.salary <= s.hisalary;
SELECT e.ename,e.salary, s.grade FROM salarygrade s JOIN emp e ON e.salary >= s.losalary AND e.salary <= s.hisalary;
SELECT e.ename,e.salary, s.grade FROM salarygrade s JOIN emp e ON e.salary BETWEEN s.losalary AND s.hisalary;
SELECT e.ename,e.salary, s.grade FROM salarygrade s, emp e WHERE e.salary BETWEEN s.losalary AND s.hisalary;
4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
SELECT e.ename,e.salary,s.grade,d.dname,d.loc,j.jname,j.description FROM salarygrade s, emp e,dept d,job j WHERE e.dept_id = d.id AND e.job_id = j.id AND e.salary >= s.losalary AND e.salary <= s.hisalary;
SELECT e.ename,e.salary,s.grade,d.dname,d.loc