From 27af025390f1eb3198fe92e233369108745da129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E8=B5=B7=E7=91=9E?= <3148024859@qq.com> Date: Wed, 22 Feb 2023 23:13:07 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...20230222 MySQL\347\272\246\346\235\237.md" | 368 ++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 "50 \345\274\240\350\265\267\347\221\236/20230222 MySQL\347\272\246\346\235\237.md" diff --git "a/50 \345\274\240\350\265\267\347\221\236/20230222 MySQL\347\272\246\346\235\237.md" "b/50 \345\274\240\350\265\267\347\221\236/20230222 MySQL\347\272\246\346\235\237.md" new file mode 100644 index 0000000..ef21e33 --- /dev/null +++ "b/50 \345\274\240\350\265\267\347\221\236/20230222 MySQL\347\272\246\346\235\237.md" @@ -0,0 +1,368 @@ +## MySQL约束 + +约束:主键、唯一、非空、默认、自增、外键 + +#### 主键约束 + +1. 关键字是primary key +2. 特点:每一个表当中只能有一个主键约束 +3. 主键约束的字段值不允许为null值 +4. 不允许重复 + +解决方法.1:单独使用一个id列当主键 + +解决方法2:复合主键 + +```mysql +create table xuanke( + sid int, + cid int, + score int, + primary key(sid,cid) #它俩组合不能为 null ,并且唯一 +); +``` + +建表后增加约束 + +```mysql +alter table 表名称 add primary key(字段列表); +``` + +如果是一个字段,就是一个字段是主键 (字段列表)如果是多个字段,就是复合主键 + +如果想要删除主键约束 + +```mysql +alter table 表名称 drop primary key; +alter table student dtop primary key; +``` + +#### 唯一键约束 + +1. 关键字:unique key +2. 特点:允许为null +3. 不能重复 +4. 一个表可以有多个唯一键约束 + +建表后增加唯一键约束 + +```mysql +alter table 表名称 add unique key (字段列表); +alter table student add unique key (sname); +``` + +如果用语句删除唯一键约束 + +```mysql +alter table 表名称 drop index 索引名; +``` + +#### 非空约束 + +```mysql +not null # 不允许为空 +``` + +#### 默认值约束 + +如果某个字段,在添加数据时未指定值时,希望不要用null处理而是按照一个默认值处理,就可以使用默认值约束 + +```mysql +default +``` + +删除score的非空约束 + +```mysql +alter table student modify score int; +``` + +增加非空约束 + +```mysql +alter table student modify score int not null; +``` + +删除gender的默认值约束 保留非空约束 + +```mysql +alter table student modify gender enum('男','女') not null; +``` + +#### 检查约束 + +MySQL5.7不支持check约束,在MySQL中开始支持check约束 + +#### 外键约束 + +约束俩个表的关系,或者是一个表的俩个字段之间的关系 + +(1)主表(父表)和从表(子表) 主表:被依赖,被参考 从表:依赖别人的,参考别人的 + +例如:学生表、课程表、选课表 选课表中的学号,它的值是依赖于学生表的学号。 选课表是从表, 学生表是主表。 选课表中的课程编号,它的值是依赖于课程表的课程编号。 选课表是从表, 课程表示主表。 + +(2)外键的建立和指定要在从表中定义 (3)关键字 foreign key (4)格式 + +```mysql +foreign key (从表的字段) references 主表(被依赖字段[主键]) +``` + +(5)要求 A:主表必须先存在 B:主表被依赖字段必须有索引,所以通常是主键列或唯一键列等才能作为被依赖字段。 C:删除表时,要么先删除从表,再删除主表,要么先解除外键约束,然后各自删除。 D:从(子)表的依赖字段的数据,必须在主(父)表被依赖字段中选择。 添加和修改都是这样的。 E:主(父)表被依赖字段的数据不能轻易的删除和修改,要看是否被引用 + +```my +外键约束等级为 on update/delete cascade /(set null) +``` + +7、自增属性 维护某个字段的值自动增长的一个属性。 它的要求: (1)一个表最多只能有一个字段是自增的 (2)自增的字段必须是整数类型 (3)自增的字段必须是键约束的字段(通常是主键、唯一键) + +自增字段赋值为null和0的时候,会自增, 如果赋值为其他的值,按照你指定的值来。 + +```mysql +ALTER TABLE 表名称 AUTO_INCREMENT = 起始值; + +``` + +--- + +## 作业 + +### 第一题 + +```mysql + +-- 1、创建数据库test01_company +-- +CREATE DATABASE test01_company CHARSET utf8; +use test01_company; +-- 2、创建表格offices + +-- | 字段名 | 数据类型 | +-- | ---------- | ----------- | +-- | officeCode | int | +-- | city | varchar(30) | +-- | address | varchar(50) | +-- | country | varchar(50) | +-- | postalCode | varchar(25) | +CREATE TABLE offices( +officecode int, +city VARCHAR(30), +address varchar(50), +country VARCHAR(50), +postalcode VARCHAR(25)); +-- 3、创建表格employees +-- +-- | 字段名 | 数据类型 | +-- | --------- | ------------- | +-- | empNum | int(11) | +-- | lastName | varchar(50) | +-- | firstName | varchar(50) | +-- | mobile | varchar(25) | +-- | code | int | +-- | jobTitle | varchar(50) | +-- | birth | date | +-- | Note | varchar(255) | +-- | Sex | varchar(5) | +CREATE table employees( +empNum int, +lastName VARCHAR(50), +firstName VARCHAR(50), +mobile VARCHAR(25), +code int, +jobTitle VARCHAR(50), +birth date, +Note VARCHAR(50), +Sex VARCHAR(5)); +-- **要求4:**将表employees的mobile字段修改到code字段后面。 +alter table employees MODIFY mobile VARCHAR(25) after code; +-- **要求5:**将表employees的birth字段改名为birthday; +alter table employees change birth birthday date; +-- **要求6:**修改sex字段,数据类型为char(1)。 +alter table employees MODIFY sex char(1); +-- **要求7:**删除字段note; +alter table employees drop note; +-- **要求8:**增加字段名favoriate_activity,数据类型为varchar(100); +alter table employees add favoriate_activity varchar(100); +-- **要求9:**将表employees的名称修改为 employees_info +alter table employees rename to employees_info; +``` + +### 第二题 + +```mysql +-- 1、创建数据库test02db +CREATE DATABASE test02db; +-- 2、创建表格pet +use test02db; +-- | 字段名 | 字段说明 | 数据类型 | +-- | ------- | -------- | ----------- | +-- | name | 宠物名称 | varchar(20) | +-- | owner | 宠物主人 | varchar(20) | +-- | species | 种类 | varchar(20) | +-- | sex | 性别 | char(1) | +-- | birth | 出生日期 | year | +-- | death | 死亡日期 | year | +CREATE TABLE pet( +name VARCHAR(20), +owner VARCHAR(20), +species VARCHAR(20), +sex char(1), +birth year, +death year); +-- 3、添加记录 +-- +-- | name | owner | species | sex | birth | death | +-- | ------ | ------ | ------- | ---- | ----- | ----- | +-- | Fluffy | harold | Cat | f | 2003 | 2010 | +-- | Claws | gwen | Cat | m | 2004 | | +-- | Buffy | | Dog | f | 2009 | | +-- | Fang | benny | Dog | m | 2000 | | +-- | bowser | diane | Dog | m | 2003 | 2009 | +-- | Chirpy | | Bird | f | 2008 | | +INSERT into pet VALUES('Fluffy','harold','Cat','f',2003,2010),('Claws','gwen','Cat','m',2004,null),('Buffy',null,'Dog','f',2009,null),('Fang','benny','Dog','m',2000,null),('bowser','diane','Dog','m',2003,2009),('Chirpy',null,'Bird','f',2008,null); +SELECT * from pet; +-- 4、 添加字段主人的生日owner_birth。 +alter table pet add owner_birth VARCHAR(10); +-- 5、 将名称为Claws的猫的主人改为kevin +UPDATE pet set owner='kevin' WHERE name='Claws'; +SELECT * from pet; +-- 6、 将没有死的狗的主人改为duck +UPDATE pet set owner='duck' WHERE name='Fang'; +SELECT * from pet; +-- 7、 查询没有主人的宠物的名字; +SELECT * from pet where isnull(owner); +SELECT owner from pet where isnull; +-- 8、 查询已经死了的cat的姓名,主人,以及去世时间; +select name,owner,death from pet where death !='' and species='Cat'; +-- 9、 删除已经死亡的狗 +delete FROM pet where death !=''and species='Dog'; +-- 10、查询所有宠物信息 +SELECT * from pet; +``` + +### 第三题 + +```mysql +-- 1、创建数据库:test03_company +create database test03_company charset utf8; +-- 2、在此数据库下创建如下3表,数据类型,宽度,是否为空根据实际情况自己定义。 +-- A.部门表(department): +-- 部门编号(depid),部门名称(depname),部门简介(deinfo);其中部门编号为主键。 +use test03_company ; +create table department( +depid int primary key auto_increment, +depname char(10) not null unique key, +deinfo varchar(200) +); +-- B.雇员表(employee):雇员编号(empid),姓名(name),性别(sex),职称(title),出生日期(birthday),所在部门编号(depid);其中 +-- * ​ 雇员编号为主键; +-- * ​ 部门编号为外键,外键约束等级为(on update cascade 和on delete set null); +-- * ​ 性别默认为男; +create table employee ( +empid int primary key auto_increment, +name varchar(10) not null, +sex enum('男','女') not null default '男', +title varchar(10), +birthday date, +depid int, +foreign key (depid) references department(depid) +); + +-- C.工资表(salary):雇员编号(empid),基本工资(basesalary),职务工资(titlesalary),扣除(deduction)。其中雇员编号为主键。 + +-- 3、给工资表(salary)的雇员编号(empid)增加外键约束,外键约束等级为(on update cascade 和on delete cascade) +CREATE table salary( +empid int PRIMARY key auto_increment, +basesalary VARCHAR(50), +titlesalary VARCHAR(50), +deduction VARCHAR(50), +FOREIGN key (empid) REFERENCES employee(empid) +); +-- 4、添加数据如下: +-- 部门表: +-- | 部门编号 | 部门名称 | 部门简介 | +-- | -------- | -------- | ------------ | +-- | 111 | 生产部 | Null | +-- | 222 | 销售部 | Null | +-- | 333 | 人事部 | 人力资源管理 | +insert into department VALUES(111,'生产部',null),(222,'销售部',null),(333,'人事部','人力资源管理'); +-- 雇员表: + +-- | 雇员编号 | 姓名 | 性别 | 职称 | 出生日期 | 所在部门编号 | +-- | -------- | ---- | ---- | ---------- | ---------- | ------------ | +-- | 1001 | 张三 | 男 | 高级工程师 | 1975-1-1 | 111 | +-- | 1002 | 李四 | 女 | 助工 | 1985-1-1 | 111 | +-- | 1003 | 王五 | 男 | 工程师 | 1978-11-11 | 222 | +-- | 1004 | 张六 | 男 | 工程师 | 1999-1-1 | 222 | +INSERT into employee VALUES(1001,'张三','男','高级工程师','1975-1-1',111),(1002,'李四','女','助工','1985-1-1',111),(1003,'王五','男','工程师','1978-11-11',222),(1004,'张六','男','工程师','1999-1-1',222); +-- 工资表: + +-- | 雇员编号 | 基本工资 | 职务工资 | 扣除 | +-- | -------- | -------- | -------- | ---- | +-- | 1001 | 2200 | 1100 | 200 | +-- | 1002 | 1200 | 200 | NULL | +-- | 1003 | 2900 | 700 | 200 | +-- | 1004 | 1950 | 700 | 150 | +insert into salary VALUES(1001,2200,1100,200),(1002,1200,200,null),(1003,2900,700,200),(1004,1950,700,150); +``` + +### 第四题 + +```mysql +-- 1、创建一个数据库:test04_school +-- +CREATE DATABASE test04_school CHARSET utf8; +-- 2、创建如下表格 +-- +-- 表1 Department表的定义 +-- +-- | **字段名** | **字段描述** | **数据类型** | **主键** | **外键** | **非空** | **唯一** | +-- | ---------- | ------------ | ------------ | -------- | -------- | -------- | -------- | +-- | DepNo | 部门号 | int(10) | 是 | 否 | 是 | 是 | +-- | DepName | 部门名称 | varchar(20) | 否 | 否 | 是 | 否 | +-- | DepNote | 部门备注 | Varchar(50) | 否 | 否 | 否 | 否 | +use test04_school; +CREATE table department( +DepNo int not null PRIMARY key unique key, +DepName VARCHAR(50) not null, +DepNote varchar(50)); +-- 表2 Teacher表的定义 +-- +-- | **字段名** | **字段描述** | **数据类型** | **主键** | **外键** | **非空** | **唯一** | +-- | ---------- | ------------ | ------------ | -------- | -------- | -------- | -------- | +-- | Number | 教工号 | int | 是 | 否 | 是 | 是 | +-- | Name | 姓名 | varchar(30) | 否 | 否 | 是 | 否 | +-- | Sex | 性别 | varchar(4) | 否 | 否 | 否 | 否 | +-- | Birth | 出生日期 | date | 否 | 否 | 否 | 否 | +-- | DepNo | 部门号 | int | 否 | 是 | 否 | 否 | +-- | Salary | 工资 | float | 否 | 否 | 否 | 否 | +-- | Address | 家庭住址 | varchar(100) | 否 | 否 | 否 | 否 | +CREATE table teacher( +Number int not null primary key unique key, +Name VARCHAR(30)not null, +Sex varchar(4), +Birth date, +DepNo int, +Salary float, +Address varchar(100), +FOREIGN key (DepNo)REFERENCES department(DepNo)); +-- 3、添加记录 +-- +-- | **DepNo** | **DepName** | **DepNote** | +-- | --------- | ----------- | ------------------ | +-- | 601 | 软件技术系 | 软件技术等专业 | +-- | 602 | 网络技术系 | 多媒体技术等专业 | +-- | 603 | 艺术设计系 | 广告艺术设计等专业 | +-- | 604 | 管理工程系 | 连锁经营管理等专业 | +INSERT into department VALUES(601,'软件技术系','软件技术等专业'),(602,'网络技术系','多媒体技术等专业'),(603,'艺术设计系','广告艺术设计等专业'),(604,'管理工程系','连锁经营管理等专业'); +-- | **Number** | **Name** | **Sex** | **Birth** | **DepNo** | **Salary** | **Address** | +-- | ---------- | -------- | ------- | ---------- | --------- | ---------- | ------------ | +-- | 2001 | Tom | 女 | 1970-01-10 | 602 | 4500 | 四川省绵阳市 | +-- | 2002 | Lucy | 男 | 1983-12-18 | 601 | 2500 | 北京市昌平区 | +-- | 2003 | Mike | 男 | 1990-06-01 | 604 | 1500 | 重庆市渝中区 | +-- | 2004 | James | 女 | 1980-10-20 | 602 | 3500 | 四川省成都市 | +-- | 2005 | Jack | 男 | 1975-05-30 | 603 | 1200 | 重庆市南岸区 | +INSERT into teacher VALUES(2001,'Tom','女','1970-01-10',602,4500,'四川省绵阳市'),(2002,'Lucy','男','1983-12-18',601,2500,'北京市昌平区'),(2003,'Mike','男','1990-06-01',604,1500,'重庆市渝中区'),(2004,'James','女','1980-10-20',602,3500,'四川省成都市'),(2005,'Jack','男','1975-05-30',603,1200,'重庆市南岸区'); +-- 4、用SELECT语句查询Teacher表的所有记录。 +SELECT*from teacher; +``` + -- Gitee From 930ad279bf7f106c3f720d88a613c1d11a12db10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E8=B5=B7=E7=91=9E?= <3148024859@qq.com> Date: Fri, 24 Feb 2023 12:22:11 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...14\350\277\220\347\256\227\347\254\246.md" | 361 ++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 "50 \345\274\240\350\265\267\347\221\236/20230224 select\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" diff --git "a/50 \345\274\240\350\265\267\347\221\236/20230224 select\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" "b/50 \345\274\240\350\265\267\347\221\236/20230224 select\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" new file mode 100644 index 0000000..6b0181a --- /dev/null +++ "b/50 \345\274\240\350\265\267\347\221\236/20230224 select\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" @@ -0,0 +1,361 @@ +# 2.23 查询select语句和运算符 + +### select语句格式: + +```mysql +SELECT 字段列表 FROM 表名称; + +SELECT 字段列表 FROM 表名称 WHERE 条件; +``` + +### 使用别名(临时名称) + +```mysql +select 字段名1 as "别名1", 字段名2 as "别名2" from 表名称 as 别名; +``` + +- 列的别名有空格时,请加双引号。**==列的别名==中没有空格时,双引号可以加也可以不加**。 +- ==**表的别名不能加双引号**==,表的别名中间不能包含空格。 +- as大小写都可以,as也完全可以省略。 + +```mysql +示例: +mysql> select id "学号",name "姓名" from student; ++------+------+ +| 学号 | 姓名 | ++------+------+ +| 1 | 张三 | +| 2 | 李四 | ++------+------+ +2 rows in set (0.00 sec) + +mysql> select id 学号,name 姓名 from student; ++------+------+ +| 学号 | 姓名 | ++------+------+ +| 1 | 张三 | +| 2 | 李四 | ++------+------+ +2 rows in set (0.00 sec) +``` + +### 结果去重 + +mysql可以在查询结果中使用distinct关键字去重。 + +```mysql +select distinct 字段列表 from 表名称 【where 条件】; + +示例: +select distinct did from t_employee; +``` + +### 算术运算符 + +```mysql +加:+ + 在MySQL +就是求和,没有字符串拼接 +减:- +乘:* +除:/ div(只保留整数部分) + div:两个数相除只保留整数部分 + /:数学中的除 +模:% mod + +mysql中没有 +=等运算符 +``` + +### 比较运算符 + +```mysql +大于:> +小于:< +大于等于:>= +小于等于:>= +等于:= 不能用于null判断 +不等于:!= 或 <> 不能用于null判断 +判断是null 用 is null 或 用 <=> null +判断不是null is not null +``` + +### 区间或集合范围比较运算符 + +```mysql +区间范围:between x and y + not between x and y +集合范围:in (x,x,x) + not in(x,x,x) +between ... and ... 结果包含两端的边界 + +示例: +#查询薪资在[10000,15000] +select * from t_employee where salary>=10000 && salary<=15000; +select * from t_employee where salary between 10000 and 15000; + +#查询籍贯在这几个地方的 +select * from t_employee where work_place in ('北京', '浙江', '江西'); + +#查询薪资不在[10000,15000] +select * from t_employee where salary not between 10000 and 15000; + +#查询籍贯不在这几个地方的 +select * from t_employee where work_place not in ('北京', '浙江', '江西'); +``` + +### 模糊匹配比较运算符 + +%:代表任意个字符 + +_:代表一个字符,如果两个下划线代表两个字符 + +```mysql +示例: +#查询名字中包含'冰'字 +select * from t_employee where ename like '%冰%'; + +#查询名字以‘雷'结尾的 +select * from t_employee where ename like '%远'; + +#查询名字以’李'开头 +select * from t_employee where ename like '李%'; + +#查询名字有冰这个字,但是冰的前面只能有1个字 +select * from t_employee where ename like '_冰%'; + +#查询当前mysql数据库的字符集情况 +show variables like '%character%'; +``` + +### 逻辑运算符 + +```mysql +逻辑与:&& 或 and +逻辑或:|| 或 or +逻辑非:! 或 not +逻辑异或: xor + +示例: +#查询薪资高于15000,并且性别是男的员工 +select * from t_employee where salary>15000 and gender='男'; +select * from t_employee where salary>15000 && gender='男'; + +select * from t_employee where salary>15000 & gender='男';#错误得不到值 &按位与 +select * from t_employee where (salary>15000) & (gender='男'); + +#查询薪资高于15000,或者did为1的员工 +select * from t_employee where salary>15000 or did = 1; +select * from t_employee where salary>15000 || did = 1; + +#查询薪资不在[15000,20000]范围的 +select * from t_employee where salary not between 15000 and 20000; +select * from t_employee where !(salary between 15000 and 20000); + +#查询薪资高于15000,或者did为1的员工,两者只能满足其一 +select * from t_employee where salary>15000 xor did = 1; +select * from t_employee where (salary>15000) ^ (did = 1); +``` + +### 关于null值的问题、 + +```mysql +#(1)判断时 +xx is null +xx is not null +xx <=> null + +#(2)计算时 +ifnull(xx,代替值) 当xx是null时,用代替值计算 + +示例: +#查询员工的实发工资,实发工资 = 薪资 + 薪资 * 奖金比例 +select ename , salary + salary * commission_pct "实发工资" from t_employee; #失败,当commission_pct为null,结果都为null + +select ename ,salary , commission_pct, salary + salary * ifnull(commission_pct,0) "实发工资" from t_employee; +``` + +### 位运算符 + +```mysql +左移:<< +右移:>> +按位与:& +按位或:| +按位异或:^ +按位取反:~ +``` + + + +# 作业 + +## 第1题:员工表 + +| **id** | **name** | **sex** | **tel** | **addr** | **salary** | +| ------ | -------- | ------- | ------------ | -------- | ---------- | +| 10001 | 张一一 | 男 | 13456789000 | 广东韶关 | 10010.58 | +| 10002 | 刘小红 | 女 | 13454319000 | 广东江门 | 12010.21 | +| 10003 | 李四 | 男 | 0751-1234567 | 广东佛山 | 10040.11 | +| 10004 | 刘小强 | 男 | 0755-5555555 | 广东深圳 | 15010.23 | +| 10005 | 王艳 | 女 | NULL | 广东广州 | 14050.16 | + +```mysql +CREATE DATABASE test03 CHARSET utf8; +USE test03; + +CREATE TABLE employee( + id INT, + `name` VARCHAR(20), + sex VARCHAR(20), + tel VARCHAR(20), + addr VARCHAR(50), + salary FLOAT +); + +INSERT INTO employee(id,`name`,sex,tel,addr,salary)VALUES +(10001,'张一一','男','13456789000','广东韶关',10010.58), +(10002,'刘小红','女','13454319000','广东江门',12010.21), +(10003,'李四','男','0751-1234567','广东佛山',10040.11), +(10004,'刘小强','男','0755-5555555','广东深圳',15010.23), +(10005,'王艳','男',NULL,'广东广州',14050.16); +``` + +**要求1:**查询出薪资在12000~13000之间的员工信息。 + +```mysql +SELECT * FROM employee WHERE salary BETWEEN 12000 AND 13000; +``` + +**要求2:**查询出姓“刘”的员工的工号,姓名,家庭住址。 + +```mysql +SELECT id,`name`,addr FROM employee WHERE `name` LIKE '刘%'; +``` + +**要求3:**将“李四”的家庭住址改为“广东韶关” + +```mysql +UPDATE employee SET addr = '广东韶关' WHERE `name` = '李四'; +``` + +**要求4:**查询出名字中带“小”的员工 + +```mysql +SELECT `name` FROM employee WHERE `name` LIKE '%小%'; +``` + +**要求5:**查询出薪资高于11000的男员工信息 + +```mysql +SELECT * FROM employee WHERE salary>11000 AND sex='男'; +``` + +**要求6:**查询没有登记电话号码的员工 + +```mysql +SELECT `name` FROM employee WHERE tel is NULL; +``` + +**要求7:**查询薪资高于12000或者家是广东深圳、广州的男员工 + +```mysql +SELECT `name` FROM employee WHERE sex = '男' AND salary = 12000 OR addr = '广东深圳' OR addr='广东广州'; +``` + +**要求8:**查询每个员工的年薪,显示“姓名、年薪” + +```mysql +SELECT `name`,salary FROM employee; +``` + + + +## 第2题:国家信息表 + +countries_info表中存储了国家名称、所属大陆、面积、人口和 GDP 值。 + +```mysql +DROP TABLE IF EXISTS `countries_info`; +CREATE TABLE `countries_info`( + `name` VARCHAR(100), + `continent` VARCHAR(100), + `area` INT, + population INT, + gdp BIGINT +); + +INSERT INTO countries_info VALUES +('Afghanistan','Asia',652230,25500100,20343000000), +('Albania','Europe',28748,2831741,12960000000), +('Algeria','Africa',2381741,37100000,188681000000), +('Andorra','Europe',468,78115,3712000000), +('Angola','Africa',1246700,20609294,100990000000); +``` + +表数据样例: + +```mysql ++-------------+-----------+---------+------------+--------------+ +| name | continent | area | population | gdp | ++-------------+-----------+---------+------------+--------------+ +| Afghanistan | Asia | 652230 | 25500100 | 20343000000 | +| Albania | Europe | 28748 | 2831741 | 12960000000 | +| Algeria | Africa | 2381741 | 37100000 | 188681000000 | +| Andorra | Europe | 468 | 78115 | 3712000000 | +| Angola | Africa | 1246700 | 20609294 | 100990000000 | ++-------------+-----------+---------+------------+--------------+ +``` + +**要求1:** 查询大国 的国家名称、人口和面积。 + +如果一个国家满足下述两个条件之一,则认为该国是 大国 : + +- 面积至少为 300万平方公里(即,3000000 km2) + +- 人口至少为 2500 万(即 25000000) + + ```mysql + SELECT `name`,area,population FROM countries_info WHERE area>3000000 OR population>=25000000; + ``` + +**要求2:**查询属于亚洲的国家名称、所属大陆、面积、人口和 GDP 值 + +```mysql +SELECT * FROM countries_info WHERE continent = 'Asia'; +``` + +**要求3:**查询国土面积不足1万平方公里且人口不走10万人的国家信息 + +```mysql +SELECT * FROM countries_info WHERE area<10000 AND population<100000; +``` + +**要求4:**查询国家名字中包含“o“字母的国家信息 + +```mysql +SELECT * FROM countries_info WHERE `name` LIKE '%o%'; +``` + +**要求5:**查询GDP值超过10000000000的国家信息 + +```mysql +SELECT * FROM countries_info WHERE gdp>10000000000; +``` + +**要求6:**查询每个国家的人均贡献GDP值(GDP/人口总数)并显示为“国家名、人口、GDP值、人均贡献GDP值” + +```mysql +SELECT `name` 国家名,population 人口,gdp GDP值,gdp/population AS 人均贡献GDP值 FROM countries_info; +``` + +**要求7:**查询人均贡献GDP值低于1000的国家信息。 + +```mysql +SELECT * FROM countries_info WHERE gdp/population<1000; +``` + +**要求8:**查询每个国家的人均国土面积(面积/人口总数)并显示为“国家名、面积、人口、人均国土面积值” + +```mysql +SELECT `name` 国家名,population 人口,gdp GDP值,area/population AS 人均国土面积值 FROM countries_info; +``` + -- Gitee From eecc40811ba7534224153852e56d68422a5102bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E8=B5=B7=E7=91=9E?= <3148024859@qq.com> Date: Thu, 2 Mar 2023 11:56:29 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E7=AC=AC=E5=9B=9B=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...72\347\241\200\347\254\224\350\256\260.md" | 51 ++ ...24\350\241\250\346\237\245\350\257\242.md" | 554 ++++++++++++++++++ 2 files changed, 605 insertions(+) create mode 100644 "50 \345\274\240\350\265\267\347\221\236/20230228 \350\201\224\350\241\250\346\237\245\350\257\242.md" diff --git "a/50 \345\274\240\350\265\267\347\221\236/20230220 MySQL\344\271\240\351\242\230\345\217\212\345\237\272\347\241\200\347\254\224\350\256\260.md" "b/50 \345\274\240\350\265\267\347\221\236/20230220 MySQL\344\271\240\351\242\230\345\217\212\345\237\272\347\241\200\347\254\224\350\256\260.md" index 779f52b..391e46c 100644 --- "a/50 \345\274\240\350\265\267\347\221\236/20230220 MySQL\344\271\240\351\242\230\345\217\212\345\237\272\347\241\200\347\254\224\350\256\260.md" +++ "b/50 \345\274\240\350\265\267\347\221\236/20230220 MySQL\344\271\240\351\242\230\345\217\212\345\237\272\347\241\200\347\254\224\350\256\260.md" @@ -226,9 +226,60 @@ USE test03_bookstore; 2、创建book表 ```mysql +CREATE TABLE book( + id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, + title VARCHAR(100) NOT NULL, + author VARCHAR(100) NOT NULL, + price DOUBLE(11,2) NOT NULL, + sales INT(11) NOT NULL, + stock INT(11) NOT NULL, + img_path VARCHAR(100) NOT NULL +); +``` + +3.创建用户表users,并插入数据 +```mysql +CREATE TABLE users( + id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(100) NOT NULL UNIQUE KEY, + `password` VARCHAR(100) NOT NULL , + email VARCHAR(100) +); ``` +4.创建订单表orders +```mysql +CREATE TABLE orders( + id VARCHAR(100) NOT NULL PRIMARY KEY, + order_time DATETIME NOT NULL, + total_count INT(11) NOT NULL, + total_amount DOUBLE(11,2) NOT NULL, + state INT(11) NOT NULL, + user_id INT(11) NOT NULL +); +ALTER TABLE orders ADD INDEX(user_id); +INSERT INTO orders VALUES('15294258455691','2018-06-20 00:30:45',2,50.20,0,1); +``` +5.创建订单明细表order_items +```mysql +CREATE TABLE order_items( + id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, + count INT(11) NOT NULL, + amount DOUBLE(11,2) NOT NULL, + title VARCHAR(100) NOT NULL, + `author` VARCHAR(100) NOT NULL, + price DOUBLE(11,2) NOT NULL, + img_path VARCHAR(100) NOT NULL, + order_id VARCHAR(100) NOT NULL +); +ALTER TABLE order_items ADD INDEX(order_id); +ALTER TABLE order_items CONVERT TO CHARACTER SET utf8; +INSERT INTO order_items +VALUES +(1,1,27.20,'解忧杂货店','东野圭吾',27.20,'static/img/default.jpg','15294258455691'), +(2,1,23.00,'边城','沈从文',23.00,'static/img/default.jpg','15294258455691'); +``` diff --git "a/50 \345\274\240\350\265\267\347\221\236/20230228 \350\201\224\350\241\250\346\237\245\350\257\242.md" "b/50 \345\274\240\350\265\267\347\221\236/20230228 \350\201\224\350\241\250\346\237\245\350\257\242.md" new file mode 100644 index 0000000..c557fde --- /dev/null +++ "b/50 \345\274\240\350\265\267\347\221\236/20230228 \350\201\224\350\241\250\346\237\245\350\257\242.md" @@ -0,0 +1,554 @@ +```mysql +drop database users; +create database users charset=utf8; +use users; +create table Student( +Sno varchar(20) not null comment'学号', +Sname varchar(20) not null comment'学生姓名', +Ssex varchar(20) not null comment'学生性别', +primary key(Sno), +Sbirthday datetime comment'学生出生年月', +Class varchar(20) comment'学生所在班级' +) comment'学生表'; +create table Course( +Cno varchar(20) not null comment'课程号', +Cname varchar(20) not null comment'课程名称', +primary key(Cno), +Tno varchar(20) not null comment'教工编号' +) comment'课程表'; +create table Score( +Sno varchar(20) not null comment'学号', +Cno varchar(20) not null comment'课程号', +primary key(Sno,Cno), +Degree Decimal(4,1) comment'成绩' +) comment'成绩表'; +create table Teacher( +Tno varchar(20) not null comment'教工编号', +Tname varchar(20) not null comment'教工姓名', +Tsex varchar(20) not null comment'教工性别', +Tbirthday datetime comment'教工出生年月', +Prof varchar(20) comment'职称', +primary key(Tno), +Depart varchar(20) not null comment'教工所在部门' +) comment'教师表'; +alter table Course +add foreign key(Tno) references Teacher(Tno); +insert into Student +values +(108,'曾华','男','1977-9-1',95033), +(105,'匡明','男','1975-10-2',95031), +(107,'王丽','女','1976-1-23',95033), +(101,'李军','男','1976-2-20',95033), +(109,'王芳','女','1975-2-10',95031), +(103,'陆君','男','1974-6-3',95031); +set @@foreign_key_checks=0; +insert into Course +values +('3-105','计算机导论',825), +('3-245','操作系统',804), +('6-166','数字电路',856), +('9-888','高等数学',831); +insert into Score +values +(103,'3-245',86), +(105,'3-245',76), +(109,'3-245',68), +(103,'3-105',92), +(105,'3-105',88), +(109,'3-105',76), +(101,'3-105',64), +(107,'3-105',91), +(108,'3-105',78), +(101,'6-166',85), +(107,'6-166',79), +(108,'6-166',81); +insert into Teacher +values +(804,'李诚','男','1958-12-2','副教授','计算机系'), +(856,'张旭','男','1969-3-12','讲师','电子工程系'), +(825,'王萍','女','1972-5-5','助教','计算机系'), +(831,'刘冰','女','1977-8-14','助教','电子工程系'); +set @@foreign_key_checks=1; +-- 1,查询所有学生,都学了哪些课程,要显示学生信息和课程信息/ +select * from Student inner join Course; +-- 2,查询没有学生的教师的所有信息 +select Tname from Student inner join Teacher WHERE Sno having null; +4. 查询 +① 查询Score表中的最高分的学生学号和课程号。 +select Sno,Cno from Score where Degree =92 ; +select Sno,Cno from Score WHERE Degree <=> (Select MAX(Degree) from Score); +② 查询所有学生的Sname、Cno和Degree列。 +select Sname,Cno,Degree from Student cross join Score on Student.Sno = Score.Sno ; +③ 查询所有学生的Sno、Cname和Degree列。 +select Student.Sno,Cname,Degree from Student inner join Course cross join Score on Student.Sno = Score.Sno and Course.Cno = Score.Cno; +④ 查询所有学生的Sname、Cname和Degree列。 +select Sname,Cname,Degree from Student inner join Course cross join Score on Student.Sno = Score.Sno and Course.Cno = Score.Cno ; +⑤ 查询“95033”班学生的平均分。 +select AVG(Degree),Class from Student inner join Score on Student.Sno = Score.Sno where Class=95033; +⑥ 查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。 +select Sno from Score where Degree > 76; +select Sno from Score where Degree> (select Degree from Score where Cno = '3-105' and Sno = 109) ; +⑦ 查询score中选学多门课程的同学中分数为非最高分成绩的记录。 +select Degree from Score where Degree < (select MAX(Degree) from Score); +⑧ 查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。 +select * from Score where Degree >76; +select * from Score where Degree> (select Degree from Score where Cno = '3-105' and Sno = 109) ; +⑨ 查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。 + +⑩ 查询“张旭“教师任课的学生成绩。 +select Degree from Teacher inner join Score where Tname='张旭'; +11 查询选修某课程的同学人数多于5人的教师姓名。 +select distinct Tname from Score inner join Teacher where Sno >5; +12 查询出“计算机系“教师所教课程的成绩表。 +select distinct Degree from Teacher inner join Score where Depart ='计算机系'; +13 查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。 +select Tname,Prof from Teacher where Depart ='计算机系' or Depart ='电子工程系'; +14 查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。 +select Cno,Sno,Degree from Score where Cno ='3-105' xor Degree > Cno ='3-245' xor Degree order by Degree desc ; +15 查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree. +select Cno,Sno,Degree from Score where Cno ='3-105' xor Degree > Cno ='3-245' xor Degree; +16 查询成绩比该课程平均成绩低的同学的成绩表。 +select Degree from Score where Degree <(select AVG(Degree) from Score); +17 查询所有任课教师的Tname和Depart. +select Tname,Depart from Teacher; +18 查询所有未讲课的教师的Tname和Depart. +select Tname,Depart from Teacher inner join Course where Cname is null; +19 查询“男”教师及其所上的课程。 +select Tname,Tsex,Cname from Teacher inner join Course where Tsex ='男'; +20 查询最高分同学的Sno、Cno和Degree列。 +select Sno,Cno,Degree from Score where Degree =92; +select Sno,Cno,Degree from Score where Degree = (select MAX(Degree) from Score); +21 查询和“李军”同性别的所有同学的Sname. +select Sname from Student where Ssex ='男' and Sname != '李军'; +22 查询和“李军”同性别并同班的同学Sname. +select Sname from Student where Ssex ='男' and Sname != '李军' and Class ='95033'; +23 查询所有选修“计算机导论”课程的“男”同学的成绩表。 +select Degree from Course inner join Score cross join Student on Student.Sno = Score.Sno where Cname ='计算机导论' and Ssex ='男'; + +``` + +笔记 + +- **什么是分组查询?** + +> 将查询结果按照1个或多个字段进行分组,字段值相同的为一组 +> 其实就是按照某一列进行分类 + +- **分组使用** + +> **SELECT gender from employee GROUP BY gender;** +> +> 根据gender字段来分组,gender字段的全部值只有两个('男'和'女'),所以分为了两组 +> 当group by单独使用时,只显示出每一组的第一条记录 +> 所以group by单独使用时的实际意义不大 + +![img](https://pic3.zhimg.com/80/v2-2dd056cc432e89898c80cbacf78c3dda_720w.webp) + +对这个表进行GROUP BY操作 + +```text +SELECT * FROM employee; +``` + +![img](https://pic3.zhimg.com/80/v2-650d569e895acc26b20d0a0edc2596e6_720w.webp) + +只显示了每一组第一条记录 + +男生的第一个人是张三 女生的第一个人是王五 + +![img](https://pic2.zhimg.com/80/v2-a289b4d4803b3e9869656420f5c87d75_720w.webp) + +所以说GROUP BY 一般不单独使用 + + + +**一般来说 你按照什么分组 就查询什么东西** + +**比如:** + +```sql +select department from employee group by department; +``` + +查询结果如上。 + +**分完组然后呢?** + +- **如何对分组后的结果进行查询?** + +**关键字:group_concat()** + +将职员表 按照部门分组 查询每个部门职员的姓名 + +```sql +select department,group_concat(name) from employee group by department; +``` + +结果如下: + +![img](https://pic2.zhimg.com/80/v2-ae5227cf66ecdc638e79980dede53499_720w.webp) + +------ + +- **GROUP BY + 聚合函数** + +**for example:** + +将职员表 按照部门分组 查询每个部门职员的薪水 和 **薪水总数** + +```sql +select department,group_concat(salary),sum(salary) from employee group by department; +``` + +![img](https://pic1.zhimg.com/80/v2-9b5ca13455b29ebcf2e598d38ea87754_720w.webp) + +> 查询每个部门的名称 以及 每个部门的人数 + +```mysql +select department,group_concat(name),count(*) from employee group by department; +``` + +> 查询每个部门的部门名称 以及 每个部门工资大于1500的人数 + +PS:**先把大于1500的人查出来 再做分组** + +```sql +select department,group_concat(salary),count(*) from employee group by department; +``` + +------ + +**group by + having** + +- 用来分组**查询后**制定一些条件来输出查询结果 +- having的作用和where一样,但having只能用于group by +- 查询工资总和大于9000的部门名称以及工资和 + +```sql +SELECT department,GROUP_CONCAT(salary),SUM(salary) FROM employee +GROUP BY department HAVING SUM(salary) > 9000; +``` + +- having和where的区别 + +> having是在分组后对数据进行过滤 +> where是在分组前对数据进行过滤 +> having后面可以使用分组函数(统计函数) +> where后面不可以使用分组函数 +> where是对分组前记录的条件,如果某行记录没有满足where子句的条件,那么这行记录不会参加分组;而having是对分组后数据的约束 + + + +- 查询工资和大于2000的 工资总和大于6000的部门名称以及工资和 + +```sql +SELECT department,GROUP_CONCAT(salary).SUM(salary) FROM employee +WHERE salary > 2000 +GROUP BY department +HAVING SUNM(salary) > 9000 +ORDER BY SUM(salary) DESC; +//降序排列 +``` + +------ + +**书写顺序** + +![img](https://pic3.zhimg.com/80/v2-166d3cee10b01a68e90af2a5d5ed9866_720w.webp) + +------ + +**Limit的使用** + +![img](https://pic3.zhimg.com/80/v2-cc55920af6e230cfe251bf53dd35a9c6_720w.webp) + +```sql +SELECT * FROM employee LIMIT 3,3; +``` + +**从第三行开始 取三条数据** + +**PS:行是从0开始数的** + +![img](https://pic3.zhimg.com/80/v2-320efb37091a14d6e9b35e997c81941a_720w.webp) + +![img](https://pic1.zhimg.com/80/v2-29ecf40b5281d6f98d6a78ecac889ab8_720w.webp) + +------ + +**limit可以用于分页操作** + +![img](https://pic3.zhimg.com/80/v2-71ce51c3e1d647067bc562f362b88ee6_720w.webp) + +- **什么是分组查询?** + +> 将查询结果按照1个或多个字段进行分组,字段值相同的为一组 +> 其实就是按照某一列进行分类 + +- **分组使用** + +> **SELECT gender from employee GROUP BY gender;** +> +> 根据gender字段来分组,gender字段的全部值只有两个('男'和'女'),所以分为了两组 +> 当group by单独使用时,只显示出每一组的第一条记录 +> 所以group by单独使用时的实际意义不大 + +![img](https://pic3.zhimg.com/80/v2-2dd056cc432e89898c80cbacf78c3dda_720w.webp) + +对这个表进行GROUP BY操作 + +```text +SELECT * FROM employee; +``` + +![img](https://pic3.zhimg.com/80/v2-650d569e895acc26b20d0a0edc2596e6_720w.webp) + +只显示了每一组第一条记录 + +男生的第一个人是张三 女生的第一个人是王五 + +![img](https://pic2.zhimg.com/80/v2-a289b4d4803b3e9869656420f5c87d75_720w.webp) + +所以说GROUP BY 一般不单独使用 + + + +**一般来说 你按照什么分组 就查询什么东西** + +**比如:** + +```text +select department from employee group by department; +``` + +![img](https://pic2.zhimg.com/80/v2-9f78a7bd599627321b0323af525d6ff9_720w.webp) + +查询结果如上。 + +**分完组然后呢?** + +- **如何对分组后的结果进行查询?** + +**关键字:group_concat()** + +将职员表 按照部门分组 查询每个部门职员的姓名 + +```text +select department,group_concat(name) from employee group by department; +``` + +结果如下: + +![img](https://pic2.zhimg.com/80/v2-ae5227cf66ecdc638e79980dede53499_720w.webp) + +------ + +- **GROUP BY + 聚合函数** + +**for example:** + +将职员表 按照部门分组 查询每个部门职员的薪水 和 **薪水总数** + +```text +select department,group_concat(salary),sum(salary) from employee group by department; +``` + +![img](https://pic1.zhimg.com/80/v2-9b5ca13455b29ebcf2e598d38ea87754_720w.webp) + +> 查询每个部门的名称 以及 每个部门的人数 + +```mysql +select department,group_concat(name),count(*) from employee group by department; +``` + +> 查询每个部门的部门名称 以及 每个部门工资大于1500的人数 + +PS:**先把大于1500的人查出来 再做分组** + +```sql +select department,group_concat(salary),count(*) from employee group by department; +``` + +------ + +**group by + having** + +- 用来分组**查询后**制定一些条件来输出查询结果 +- having的作用和where一样,但having只能用于group by +- 查询工资总和大于9000的部门名称以及工资和 + +```sql +SELECT department,GROUP_CONCAT(salary),SUM(salary) FROM employee +GROUP BY department HAVING SUM(salary) > 9000; +``` + +- having和where的区别 + +> having是在分组后对数据进行过滤 +> where是在分组前对数据进行过滤 +> having后面可以使用分组函数(统计函数) +> where后面不可以使用分组函数 +> where是对分组前记录的条件,如果某行记录没有满足where子句的条件,那么这行记录不会参加分组;而having是对分组后数据的约束 + + + +- 查询工资和大于2000的 工资总和大于6000的部门名称以及工资和 + +```sql +SELECT department,GROUP_CONCAT(salary).SUM(salary) FROM employee +WHERE salary > 2000 +GROUP BY department +HAVING SUNM(salary) > 9000 +ORDER BY SUM(salary) DESC; +//降序排列 +``` + +------ + +**书写顺序** + +![img](https://pic3.zhimg.com/80/v2-166d3cee10b01a68e90af2a5d5ed9866_720w.webp) + +------ + +**Limit的使用** + +![img](https://pic3.zhimg.com/80/v2-cc55920af6e230cfe251bf53dd35a9c6_720w.webp) + +```text +SELECT * FROM employee LIMIT 3,3; +``` + +**从第三行开始 取三条数据** + +**PS:行是从0开始数的** + +![img](https://pic3.zhimg.com/80/v2-320efb37091a14d6e9b35e997c81941a_720w.webp) + +![img](https://pic1.zhimg.com/80/v2-29ecf40b5281d6f98d6a78ecac889ab8_720w.webp) + +------ + +**limit可以用于分页操作** + +![img](https://pic3.zhimg.com/80/v2-71ce51c3e1d647067bc562f362b88ee6_720w.webp) + +```mysql +inner join,full outer join,left join,right jion +内部连接 inner join 两表都满足的组合 +full outer 全连 两表相同的组合在一起,A表有,B表没有的数据(显示为null),同样B表有 +A表没有的显示为(null) +A表 left join B表 左连,以A表为基础,A表的全部数据,B表有的组合。没有的为null +A表 right join B表 右连,以B表为基础,B表的全部数据,A表的有的组合。没有的为null + + +查询分析器中执行: +--建表table1,table2: +create table table1(id int,name varchar(10)) +create table table2(id int,score int) +insert into table1 select 1,'lee' +insert into table1 select 2,'zhang' +insert into table1 select 4,'wang' +insert into table2 select 1,90 +insert into table2 select 2,100 +insert into table2 select 3,70 +如表 +------------------------------------------------- +table1|table2| +------------------------------------------------- +idname|idscore| +1lee|190| +2zhang|2100| +4wang|370| +------------------------------------------------- + +以下均在查询分析器中执行 + +一、外连接 +1.概念:包括左向外联接、右向外联接或完整外部联接 + +2.左连接:left join 或 left outer join +(1)左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。 +(2)sql语句 +select * from table1 left join table2 on table1.id=table2.id +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang2100 +4wangNULLNULL +------------------------------ +注释:包含table1的所有子句,根据指定条件返回table2相应的字段,不符合的以null显示 + +3.右连接:right join 或 right outer join +(1)右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。 +(2)sql语句 +select * from table1 right join table2 on table1.id=table2.id +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang2100 +NULLNULL370 +------------------------------ +注释:包含table2的所有子句,根据指定条件返回table1相应的字段,不符合的以null显示 + +4.完整外部联接:full join 或 full outer join +(1)完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。 +(2)sql语句 +select * from table1 full join table2 on table1.id=table2.id +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang2100 +4wangNULLNULL +NULLNULL370 +------------------------------ +注释:返回左右连接的和(见上左、右连接) + +二、内连接 +1.概念:内联接是用比较运算符比较要联接列的值的联接 + +2.内连接:join 或 inner join + +3.sql语句 +select * from table1 join table2 on table1.id=table2.id +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang2100 +------------------------------ +注释:只返回符合条件的table1和table2的列 + +4.等价(与下列执行效果相同) +A:select a.*,b.* from table1 a,table2 b where a.id=b.id +B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件只能用where,不能用on) + +三、交叉连接(完全) + +1.概念:没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录) + +2.交叉连接:cross join (不带条件where...) + +3.sql语句 +select * from table1 cross join table2 +-------------结果------------- +idnameidscore +------------------------------ +1lee190 +2zhang190 +4wang190 +1lee2100 +2zhang2100 +4wang2100 +1lee370 +2zhang370 +4wang370 +------------------------------ +注释:返回3*3=9条记录,即笛卡尔积 + +4.等价(与下列执行效果相同) +A:select * from table1,table2 +``` \ No newline at end of file -- Gitee From 45e3c00ec4c8ca81b57940ef8f5b0642db9e3d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E8=B5=B7=E7=91=9E?= <3148024859@qq.com> Date: Thu, 9 Mar 2023 12:28:54 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E7=AC=AC=E4=BA=94=E6=AC=A1=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...9 \345\255\220\346\237\245\350\257\242.md" | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 "50 \345\274\240\350\265\267\347\221\236/20230309 \345\255\220\346\237\245\350\257\242.md" diff --git "a/50 \345\274\240\350\265\267\347\221\236/20230309 \345\255\220\346\237\245\350\257\242.md" "b/50 \345\274\240\350\265\267\347\221\236/20230309 \345\255\220\346\237\245\350\257\242.md" new file mode 100644 index 0000000..9246659 --- /dev/null +++ "b/50 \345\274\240\350\265\267\347\221\236/20230309 \345\255\220\346\237\245\350\257\242.md" @@ -0,0 +1,163 @@ +# 子查询作业 + +create table stuinfo(stuNo varchar(10), +stuName varchar(5), +stuSex enum('男','女'), +stuAge int, +stuAddress varchar(5), +stuSeat int +); +create table stuExam( +examNo int, +stuNo varchar(5), +writtenExam int, +labExam int +); +create table stuMarks( +examNo int, +stuID varchar(5), +score int +); +insert into stuinfo values('s2501','张秋利','男',20,'美国硅谷',1); +insert into stuinfo values('s2502','李斯文','女',18,'湖北武汉',2); +insert into stuinfo values('s2503','马文才','男',18,'湖南长沙',3); +insert into stuinfo values('s2504','欧阳俊雄','女',21,'湖北武汉',4); +insert into stuinfo values('s2505','梅超风','男',16,'湖北武汉',5); +insert into stuinfo values('s2506','陈旋风','男',19,'美国硅谷',6); + +insert into stuExam values(1,'s2501',50,70), +(2,'s2502',60,65), +(3,'s2503',86,70), +(4,'s2504',40,80), +(5,'s2505',70,85), +(6,'s2506',85,90); + +insert into stumarks values +(1,'s2501',88), +(2,'s2501',92), +(3,'s2501',53), +(4,'s2502',60), +(5,'s2502',99), +(6,'s2503',82); + +-- 1.查询出年龄比班上平均年龄大的学生的信息 +select avg(stuAge) from stuinfo; +select * from stuinfo where stuAge>(select avg(stuAge) from stuinfo); +-- 2.查询出每个学生的学号,姓名,性别和选修课程的最高分(stuMarks) +select stuNo,stuName,stuSex,max(score) from stuMarks a + right join stuinfo b on a.stuid=b.stuNo group by stuNo,stuName,stuSex; +-- 3.查询出每个学生的学号,姓名,性别和考试平均分(stuExam) +select stuinfo.stuNo,stuName,stuSex,avg(writtenExam+labExam)/2 考试平均分 from stuinfo left JOIN stuexam on stuinfo.stuNo=stuexam.stuNo GROUP BY stuinfo.stuNo,stuName,stuSex; +-- 4.查询性别是男并且年龄大于等于20的学生的信息(用两种方法实现:普通查询和子查询) +select * from stuinfo where stuSex='男' and stuAge >=20; +select * from (select * from stuinfo where stuAge >=20) 年纪大于20 where stuSex='男'; +-- 5.查询出年龄比所有男生年龄都大的女生的信息 +select * from stuinfo where stusex='女' and stuAge >all (select stuAge from stuinfo where stusex='男'); +-- 6.查询出所有选修课程都及格的学生的信息 (stuMarks) +select *from stuMarks where score >60; +select * from stuinfo a INNER JOIN stumarks b on a.stuNo = b.stuID where a.stuNo != (select stuid from stumarks where score<60); +-- 7.查询出参加考试的学生的信息(用表连接,in二种方法做)(stuMarks) +select * from stuinfo a inner join stumarks b on a.stuNo=b.stuId; +select * from stuinfo a inner join (select DISTINCT stuid from stumarks) b on a.stuNo = b.stuid; +select * FROM stuinfo where stuno in (select DISTINCT stuid from stumarks); +-- 8.查询出没有参加考试的学生的信息(用表连接,in二种方法做)(stuMarks) +select * from stuinfo a left join stumarks b on a.stuNO=b.stuid where score is null; +select * from stuinfo where stuno not in (select distinct stuid from stuMarks); +-- 9.将有一门成绩成绩大于90分的学生的基本信息查询出来(stuMarks) +select * from stuinfo a left join stuMarks b on a.stuNO=b.stuid where score>90; +select * from stuinfo where stuNo in (select stuid from stumarks where score >90); +-- 10.查询出平均成绩在80分以上的学生的基本信息(stuMarks) +select * from stuinfo where stuno=(select stuno from stuexam where (writtenExam+labExam)/2>80); +-- 11.查询出某同学所有考试成绩比“张秋利”同学所有分数都高的学生基本信息(stuMarks) +select * from stuinfo a left join stuExam b on a.stuNo = b.stuNo where writtenExam>(select writtenExam from stuExam where stuNo=(select stuNo from stuinfo where stuname='张秋利')) AND labExam>(select labExam from stuExam where stuNo=(select stuNo from stuinfo where stuname='张秋利')); +-- 12.查询出某同学所有考试成绩只需要比“张秋利”同学某个分数高的学生基本信息(stuMarks) +select * from stuinfo a left join stuExam b on a.stuNo = b.stuNo where writtenExam>(select writtenExam from stuExam where stuNo=(select stuNo from stuinfo where stuname='张秋利')) OR labExam>(select labExam from stuExam where stuNo=(select stuNo from stuinfo where stuname='张秋利')); +-- 13.查询班上比所有男生年龄都要大的女生的信息 +select * from stuinfo where stuSex='女' and stuAge >ALL(select stuAge from stuinfo where stusex='男'); +-- 14.查询出只要比某个男生年龄大的女生的信息 +select * from stuinfo where stuSex='女' AND stuAge >any(select stuage from stuinfo where stusex='男'); +select * from stuinfo where stuSex='女' AND stuAge >(select MIN(stuAge) from stuinfo where stusex='男'); + +## 笔记 + +##### 子查询的顺序 + +(1)from:从哪些表中筛选 + +(2)on:关联多表查询时,去除笛卡尔积 + +(3)where:从表中筛选的条件 + +(4)group by:分组依据 + +(5)having:在统计结果中再次筛选(with rollup) + +(6)order by:排序 + +(7)limit:分页 + +必须按照(1)-(7)的顺序编写子句。 + +##### on子句 + +/* +(1)on必须配合join使用 +(2)on后面只写关联条件 +所谓关联条件是两个表的关联字段的关系 +(3)有n张表关联,就有n-1个关联条件 +两张表关联,就有1个关联条件 +三张表关联,就有2个关联条件 +*/ +SELECT * +FROM t_employee INNER JOIN t_department +ON t_employee.did = t_department.did; #1个关联条件 + +#查询员工的编号,姓名,职位编号,职位名称,部门编号,部门名称 +#需要t_employee员工表,t_department部门表,t_job职位表 +SELECT eid,ename,t_job.jid,t_job.jname, `t_department`.`did`,`t_department`.`dname` +FROM t_employee INNER JOIN t_department INNER JOIN t_job +ON t_employee.did = t_department.did AND t_employee.job_id = t_job.jid; + +##### where子句 + +在查询结果中筛选 +#查询女员工的信息,以及女员工的部门信息 +SELECT * +FROM t_employee INNER JOIN t_department +ON t_employee.did = t_department.did +WHERE gender = '女'; + +##### order by子句 + +升序和降序,默认是升序 +asc代表升序 +desc 代表降序 +*/ +#查询员工信息,按照薪资从高到低 +SELECT * FROM t_employee +ORDER BY salary DESC; + +#查询每一个部门薪资超过10000的男和女员工的人数,显示部门编号,部门的名称,性别,人数 +#只显示人数低于3人,按照人数升序排列 +SELECT t_department.did,dname,gender,COUNT(eid) +FROM t_employee RIGHT JOIN t_department +ON t_employee.did = t_department.did +WHERE salary > 10000 +GROUP BY t_department.did,gender +HAVING COUNT(eid) < 3 +ORDER BY COUNT(eid); + +#查询员工的薪资,按照薪资从低到高,薪资相同按照员工编号从高到低 +SELECT * +FROM t_employee +ORDER BY salary ASC , eid DESC; + +##### 什么是子查询 + +-- 嵌套在其它SQL语句中的查询语句, + +-- 子查询通常先运行,所以要用()包括起来 + +-- 子查询的运行结果,可以做为其它语句的条件、数据源等 + +select ① from ③ where ②; -- Gitee