diff --git "a/49 \346\235\216\350\210\222\346\261\266/20230223select\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" "b/49 \346\235\216\350\210\222\346\261\266/20230223select\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" new file mode 100644 index 0000000000000000000000000000000000000000..11c81db7c351eb9363cd2e7a6bd3cda18a48523d --- /dev/null +++ "b/49 \346\235\216\350\210\222\346\261\266/20230223select\350\257\255\345\217\245\345\222\214\350\277\220\347\256\227\347\254\246.md" @@ -0,0 +1,308 @@ + + +## SELECT语句 + +SELECT语句是用于查看计算结果、或者查看从数据表中筛选出的数据的。 + +SELECT语句的基本语法: + +```java +SELECT 常量; +SELECT 表达式; +SELECT 函数; +``` + +例如: + +```java +SELECT 1; +SELECT 9/2; +SELECT NOW(); +``` + +如果要从数据表中筛选数据,需要加FROM子句。FROM指定数据来源。字段列表筛选列。 + +```java +SELECT 字段列表 FROM 表名称; +``` + +如果要从数据表中根据条件筛选数据,需要加FROM和WHERE子句。WHERE筛选行。 + +```java +SELECT 字段列表 FROM 表名称 WHERE 条件; +``` + +完整的SELECT语句后面可以跟7个子句,后面会逐一讲解。 + +## 使用别名 + +在当前select语句中给某个字段或表达式计算结果,或表等取个临时名称,便于当前select语句的编写和理解。这个临时名称称为别名。 + +```mysql +select 字段名1 as "别名1", 字段名2 as "别名2" from 表名称 as 别名; +``` + +- 列的别名有空格时,请加双引号。**==列的别名==中没有空格时,双引号可以加也可以不加**。 +- ==**表的别名不能加双引号**==,表的别名中间不能包含空格。 +- as大小写都可以,as也完全可以省略。 + +## 结果去重 + +mysql可以在查询结果中使用distinct关键字去重。 + +```mysql +select distinct 字段列表 from 表名称 【where 条件】; +``` + +```mysql +select distinct did from t_employee; +``` + +# 运算符 + +## 算术运算符 + +``` +加:+ + 在MySQL +就是求和,没有字符串拼接 +减:- +乘:* +除:/ div(只保留整数部分) + div:两个数相除只保留整数部分 + /:数学中的除 +模:% mod + +mysql中没有 +=等运算符 +``` + +## 比较运算符 + +``` +大于:> +小于:< +大于等于:>= +小于等于:>= +等于:= 不能用于null判断 +不等于:!= 或 <> 不能用于null判断 +判断是null 用 is null 或 用 <=> null +判断不是null is not null +``` + +## 区间或集合范围比较运算符 + +``` +区间范围:between x and y + not between x and y +集合范围:in (x,x,x) + not in(x,x,x) + between ... and ... 结果包含两端的边界 +``` + +## 模糊匹配比较运算符 + +%:代表任意个字符 + +_:代表一个字符,如果两个下划线代表两个字符 + +## 逻辑运算符 + +``` +逻辑与:&& 或 and +逻辑或:|| 或 or +逻辑非:! 或 not +逻辑异或: xor +``` + +## 关于null值的问题 + +``` +#(1)判断时 +xx is null +xx is not null +xx <=> null + +#(2)计算时 +ifnull(xx,代替值) 当xx是null时,用代替值计算 +``` + +## 位运算符 + +``` +左移:<< +右移:>> +按位与:& +按位或:| +按位异或:^ +按位取反:~ +``` + +# 作业 + +## 第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 | + +``` +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之间的员工信息。 + +``` +SELECT * FROM employee WHERE salary BETWEEN 12000 AND 13000; +``` + +**要求2:**查询出姓“刘”的员工的工号,姓名,家庭住址。 + +``` +SELECT id,`name`,addr FROM employee WHERE `name` LIKE '刘%'; +``` + +**要求3:**将“李四”的家庭住址改为“广东韶关” + +``` +UPDATE employee SET addr = '广东韶关' WHERE `name` = '李四'; +``` + +**要求4:**查询出名字中带“小”的员工 + +``` +SELECT `name` FROM employee WHERE `name` LIKE '%小%'; +``` + +**要求5:**查询出薪资高于11000的男员工信息 + +``` +SELECT * FROM employee WHERE salary>11000 AND sex='男'; +``` + +**要求6:**查询没有登记电话号码的员工 + +``` +SELECT `name` FROM employee WHERE tel is NULL; +``` + +**要求7:**查询薪资高于12000或者家是广东深圳、广州的男员工 + +``` +SELECT `name` FROM employee WHERE sex = '男' AND salary = 12000 OR addr = '广东深圳' OR addr='广东广州'; +``` + +**要求8:**查询每个员工的年薪,显示“姓名、年薪” + +``` +SELECT `name`,salary FROM employee; +``` + +## 第2题:国家信息表 + +countries_info表中存储了国家名称、所属大陆、面积、人口和 GDP 值。 + +``` +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); +``` + +表数据样例: + +``` ++-------------+-----------+---------+------------+--------------+ +| 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) + + ``` + SELECT `name`,area,population FROM countries_info WHERE area>3000000 OR population>=25000000; + ``` + +**要求2:**查询属于亚洲的国家名称、所属大陆、面积、人口和 GDP 值 + +``` +SELECT * FROM countries_info WHERE continent = 'Asia'; +``` + +**要求3:**查询国土面积不足1万平方公里且人口不走10万人的国家信息 + +``` +SELECT * FROM countries_info WHERE area<10000 AND population<100000; +``` + +**要求4:**查询国家名字中包含“o“字母的国家信息 + +``` +SELECT * FROM countries_info WHERE `name` LIKE '%o%'; +``` + +**要求5:**查询GDP值超过10000000000的国家信息 + +``` +SELECT * FROM countries_info WHERE gdp>10000000000; +``` + +**要求6:**查询每个国家的人均贡献GDP值(GDP/人口总数)并显示为“国家名、人口、GDP值、人均贡献GDP值” + +``` +SELECT `name` 国家名,population 人口,gdp GDP值,gdp/population AS 人均贡献GDP值 FROM countries_info; +``` + +**要求7:**查询人均贡献GDP值低于1000的国家信息。 + +``` +SELECT * FROM countries_info WHERE gdp/population<1000; +``` + +**要求8:**查询每个国家的人均国土面积(面积/人口总数)并显示为“国家名、面积、人口、人均国土面积值” + +``` +SELECT `name` 国家名,population 人口,gdp GDP值,area/population AS 人均国土面积值 FROM countries_info; +``` \ No newline at end of file diff --git "a/49 \346\235\216\350\210\222\346\261\266/20230228\345\205\263\350\201\224\346\237\245\350\257\242.md" "b/49 \346\235\216\350\210\222\346\261\266/20230228\345\205\263\350\201\224\346\237\245\350\257\242.md" new file mode 100644 index 0000000000000000000000000000000000000000..259da6eb67d9bfd85a9cd27b94a616ff6c37143b --- /dev/null +++ "b/49 \346\235\216\350\210\222\346\261\266/20230228\345\205\263\350\201\224\346\237\245\350\257\242.md" @@ -0,0 +1,561 @@ +## 什么是关联查询 + +关联查询:两个或更多个表一起查询。 + +前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立了外键,也可能没有建立外键。 + +## 关联查询的SQL有几种情况 + +1、内连接:inner join ... on + +结果:A表 ∩ B表 + +2、左连接:A left join B on + +(2)A表全部 + +(3)A表- A∩B + +3、右连接:A right join B on + +(4)B表全部 + +(5)B表-A∩B + +4、全外连接:full outer join ... on,但是mysql不支持这个关键字,mysql使用union(合并)结果的方式代替 + +(6)A表∪B表: (2) A表结果 union (4)B表的结果 + +(7)A∪B - A∩B (3)A表- A∩B结果 union (5)B表-A∩B结果 + + + +# 2.28 关联查询 + +#### 分组函数 + +| **AVG(x) :求平均值** | **SUM(x):求总和** | +| ------------------------ | -------------------- | +| **MAX(x):求最大值** | **MIN(x):求最小值** | +| **COUNT(x):统计记录数** | | + +count(*)是对满足条件的(如果没有where条件,就是对所有记录)记录累加数量 + +count(常量值)等价于count(*) + +count(字段名/表达式) 只统计非NULL值的记录数 + +#### 单行函数 + +##### 数学函数 + +| 函数 | 用法 | +| ------------- | ------------------------------------------------------------ | +| ABS(x) | 返回x的绝对值 | +| CEIL(x) | 返回大于x的最小整数值 | +| FLOOR(x) | 返回小于x的最大整数值 | +| MOD(x,y) | 返回x/y的模 | +| RAND() | 返回0~1的随机值 | +| ROUND(x,y) | 返回参数x的四舍五入的有y位的小数的值 | +| TRUNCATE(x,y) | 返回数字x截断为y位小数的结果 | +| FORMAT(x,y) | 强制保留小数点后y位,整数部分超过三位的时候以逗号分割,并且返回的结果是文本类型的 | +| SQRT(x) | 返回x的平方根 | +| POW(x,y) | 返回x的y次方 | + +##### 字符串函数 + +| 函数 | 功能描述 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| CONCAT(S1,S2,……Sn) | 连接S1,S2,……Sn为一个字符串 | +| CONCAT_WS(s,S1,S2,……Sn) | 同CONCAT(S1,S2,…)函数,但每个字符串之间要加上s | +| CHAR_LENGTH(s) | 返回字符串s的字符数 | +| LENGTH(s) | 返回字符串s的字节数,和字符集有关 | +| LOCATE(str1,str)或 POSITION(str1 in str)或 INSTR(str,str1) | 返回子字符串str1在str中的开始位置 | +| UPPER(s)或UCASE(s) | 将字符串s的所有字母转成大写字母 | +| LOWER(s)或LCASE(s) | 将字符串s的所有字母转成小写字母 | +| LEFT(s,n) | 返回字符串s最左边的n个字符 | +| RIGHT(s,n) | 返回字符串s最右边的n个字符 | +| LPAD(str,len,pad) | 用字符串pad对str最左边进行填充直到str的长度达到len | +| RPAD(str,len,pad) | 用字符串pad对str最右边进行填充直到str的长度达到len | +| LTRIM(s) | 去掉字符串s左侧的空格 | +| RTRIM(s) | 去掉字符串s右侧的空格 | +| TRIM(s) | 去掉字符串s开始与结尾的空格 | +| TRIM([BOTH] s1 FROM s) | 去掉字符串s开始与结尾的s1 | +| TRIM([LEADING] s1 FROM s) | 去掉字符串s开始处的s1 | +| TRIM([TRAILING]s1 FROM s) | 去掉字符串s结尾处的s1 | +| INSERT(str,index,len,instr) | 将字符串str从index位置开始len个字符的替换为字符串instr | +| REPLACE(str,a,b) | 用字符串b替换字符串str中所有出现的字符串a | +| REPEAT(str,n) | 返回str重复n次的结果 | +| REVERSE(s) | 将字符串反转 | +| STRCMP(s1,s2) | 比较字符串s1,s2 | +| SUBSTRING(s,index,len) | 返回从字符串s的index位置截取len个字符 | +| SUBSTRING_INDEX(str, 分隔符,count) | 如果count是正数,那么从左往右数,第n个分隔符的左边的全部内容。例如,substring_index("www.mxdx.com",".",1)是"www"。如果count是负数,那么从右边开始数,第n个分隔符右边的所有内容。例如,substring_index("www.mxdx.com",".",-1)是"com"。 | + +##### 日期时间函数 + +| 函数 | 功能描述 | +| ------------------------------------------------------------ | --------------------------------------------------- | +| CURDATE()或CURRENT_DATE() | 返回当前系统日期 | +| CURTIME()或CURRENT_TIME() | 返回当前系统时间 | +| NOW()/SYSDATE()/CURRENT_TIMESTAMP()/ LOCALTIME()/LOCALTIMESTAMP() | 返回当前系统日期时间 | +| UTC_DATE()/UTC_TIME() | 返回当前UTC日期值/时间值 | +| UNIX_TIMESTAMP(date) | 返回一个UNIX时间戳 | +| YEAR(date)/MONTH(date)/DAY(date)/ HOUR(time)/MINUTE(time)/SECOND(time) | 返回具体的时间值 | +| EXTRACT(type FROM date) | 从日期中提取一部分值 | +| DAYOFMONTH(date)/DAYOFYEAR(date) | 返回一月/年中第几天 | +| WEEK(date)/WEEKOFYEAR(date) | 返回一年中的第几周 | +| DAYOFWEEK() | 返回周几,注意,周日是1,周一是2,…周六是7 | +| WEEKDAY(date) | 返回周几,注意,周一是0,周二是1,…周日是6 | +| DAYNAME(date) | 返回星期,MONDAY,TUESDAY,…SUNDAY | +| MONTHNAME(date) | 返回月份,January,… | +| DATEDIFF(date1,date2)/TIMEDIFF(time1,time2) | 返回date1-date2的日期间隔/返回time1-time2的时间间隔 | +| DATE_ADD(date,INTERVAL expr type)或ADDDATE/DATE_SUB/SUBDATE | 返回与给定日期相差INTERVAL时间段的日期 | +| ADDTIME(time,expr)/SUBTIME(time,expr) | 返回给定时间加上/减去expr的时间值 | +| DATE_FORMAT(datetime,fmt)/ TIME_FORMAT(time,fmt) | 按照字符串fmt格式化日期datetime值/时间time值 | +| STR_TO_DATE(str,fmt) | 按照字符串fmt对str进行解析,解析为一个日期 | +| GET_FORMAT(val_type,format_type) | 返回日期时间字符串的显示格式 | + +函数中日期时间类型说明 + +| 参数类型 | 描述 | 参数类型 | 描述 | +| -------- | ---- | ------------- | -------- | +| YEAR | 年 | YEAR_MONTH | 年月 | +| MONTH | 月 | DAY_HOUR | 日时 | +| DAY | 日 | DAY_MINUTE | 日时分 | +| HOUR | 时 | DAY_SECOND | 日时分秒 | +| MINUTE | 分 | HOUR_MINUTE | 时分 | +| SECOND | 秒 | HOUR_SECOND | 时分秒 | +| WEEK | 星期 | MINUTE_SECOND | 分秒 | +| QUARTER | 一刻 | | | + +函数中format参数说明 + +| 格式符 | 说明 | 格式符 | 说明 | +| ------ | --------------------------------------------------------- | ------ | ------------------------------------------------------- | +| %Y | 4位数字表示年份 | %y | 两位数字表示年份 | +| %M | 月名表示月份(January,…) | %m | 两位数字表示月份(01,02,03,…) | +| %b | 缩写的月名(Jan.,Feb.,…) | %c | 数字表示月份(1,2,3…) | +| %D | 英文后缀表示月中的天数(1st,2nd,3rd,…) | %d | 两位数字表示表示月中的天数(01,02,…) | +| %e | 数字形式表示月中的天数(1,2,3,…) | %p | AM或PM | +| %H | 两位数字表示小数,24小时制(01,02,03,…) | %h和%I | 两位数字表示小时,12小时制(01,02,03,…) | +| %k | 数字形式的小时,24小时制(1,2,3,…) | %l | 数字表示小时,12小时制(1,2,3,…) | +| %i | 两位数字表示分钟(00,01,02,…) | %S和%s | 两位数字表示秒(00,01,02,…) | +| %T | 时间,24小时制(hh:mm:ss) | %r | 时间,12小时制(hh:mm:ss)后加AM或PM | +| %W | 一周中的星期名称(Sunday,…) | %a | 一周中的星期缩写(Sun.,Mon.,Tues.,…) | +| %w | 以数字表示周中的天数(0=Sunday,1=Monday,…) | %j | 以3位数字表示年中的天数(001,002,…) | +| %U | 以数字表示的的第几周(1,2,3,…) 其中Sunday为周中的第一天 | %u | 以数字表示年中的年份(1,2,3,…) 其中Monday为周中第一天 | +| %V | 一年中第几周(01~53),周日为每周的第一天,和%X同时使用 | %X | 4位数形式表示该周的年份,周日为每周第一天,和%V同时使用 | +| %v | 一年中第几周(01~53),周一为每周的第一天,和%x同时使用 | %x | 4位数形式表示该周的年份,周一为每周第一天,和%v同时使用 | +| %% | 表示% | | | + +GET_FORMAT函数中val_type 和format_type参数说明 + +| 值类型 | 格式化类型 | 显示格式字符串 | +| -------- | ---------- | ----------------- | +| DATE | EUR | %d.%m.%Y | +| DATE | INTERVAL | %Y%m%d | +| DATE | ISO | %Y-%m-%d | +| DATE | JIS | %Y-%m-%d | +| DATE | USA | %m.%d.%Y | +| TIME | EUR | %H.%i.%s | +| TIME | INTERVAL | %H%i%s | +| TIME | ISO | %H:%i:%s | +| TIME | JIS | %H:%i:%s | +| TIME | USA | %h:%i:%s %p | +| DATETIME | EUR | %Y-%m-%d %H.%i.%s | +| DATETIME | INTERVAL | %Y%m%d %H%i%s | +| DATETIME | ISO | %Y-%m-%d %H:%i:%s | +| DATETIME | JIS | %Y-%m-%d %H:%i:%s | +| DATETIME | USA | %Y-%m-%d %H.%i.%s | + +#### 加密函数 + +| 函数 | 用法 | +| --------------------- | ------------------------------------------------------------ | +| password(str) | 返回字符串str的加密版本,41位长的字符串 | +| md5(str) | 返回字符串str的md5值,也是一种加密方式 | +| SHA(str) | 返回字符串str的sha算法加密字符串,40位十六进制值的密码字符串 | +| SHA2(str,hash_length) | 返回字符串str的sha算法加密字符串,密码字符串的长度是hash_length/4。hash_length可以是224、256、384、512、0,其中0等同于256。 | + +#### 条件判断 + +| 函数 | 功能 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| IF(value,t,f) | 如果value是真,返回t,否则返回f | +| IFNULL(value1,value2) | 如果value1不为空,返回value1,否则返回value2 | +| CASE WHEN 条件1 THEN result1 WHEN 条件2 THEN result2 … ELSE resultn END | 依次判断条件,哪个条件满足了,就返回对应的result,所有条件都不满足就返回ELSE的result。如果没有单独的ELSE子句,当所有WHEN后面的条件都不满足时则返回NULL值结果。等价于Java中if...else if.... | +| CASE expr WHEN 常量值1 THEN 值1 WHEN 常量值2 THEN 值2 … ELSE 值n END | 判断表达式expr与哪个常量值匹配,找到匹配的就返回对应值,都不匹配就返回ELSE的值。如果没有单独的ELSE子句,当所有WHEN后面的常量值都不匹配时则返回NULL值结果。等价于Java中switch....case | + +#### 七种查询 + +###### (1)内连接 inner join + +###### (2)外连接 outer join + +左外连接 left outer join 或 left join + +右外连接 right outer join 或 right join + +全外连接 full outer join 或 full join -- union 代替 + +但是,mysql不支持全外连接,没有full join。 + +mysql使用union关键字合并其他的查询结果实现全外连接的效果。 + +内连接 ==> A∩B + +左连接 ==> A 或 A-A∩B + +右连接 ==> B 或 B-A∩B + +全外连接 ==> A∪B 或 A∪B - A∩B + +左连接的A union 右连接的B 得到 A∪B + +左连接的A-A∩B union 右连接B-A∩B 得到 A∪B - A∩B + +###### 使用union实现全外连接的效果 + +(1)A∪B + +转换为 左连接的A union 右连接的B + +(2)A∪B - A∩B + +转换为 左连接的A-A∩B union 右连接的B-A∩B + +###### 自连接 + +进行关联查询的两个表,本质上是一个表。 + +分析员工表: + +有一个字段是mid,是领导编号,即表示这个员工归谁管。 + +那么这里的领导编号其实就是这个领导他作为员工的员工编号。 + +通过取别名的方式,把一张表虚拟成两张表。 + +当然,也要关联字段。 + +# 作业 + +1. 设有一数据库,包括四个表:学生表(Student)、课程表(Course)、成绩表(Score)以及教师信息表(Teacher)。四个表的结构分别如表1-1的表(一)~表(四)所示,数据如表1-2的表(一)~表(四)所示。用SQL语句创建四个表并完成相关题目。 + +2. **数据库的表结构** + +表(一)Student (学生表) + +| 属性名 | 数据类型 | 可否为空 | 含义 | +| --------- | ------------ | -------- | ------------ | +| Sno | varchar (20) | 否 | 学号(主码) | +| Sname | varchar (20) | 否 | 学生姓名 | +| Ssex | varchar (20) | 否 | 学生性别 | +| Sbirthday | datetime | 可 | 学生出生年月 | +| Class | varchar (20) | 可 | 学生所在班级 | + +表(二)Course(课程表) + +| 属性名 | 数据类型 | 可否为空 | 含义 | +| ------ | ------------ | -------- | ---------------- | +| Cno | varchar (20) | 否 | 课程号(主码) | +| Cname | varchar (20) | 否 | 课程名称 | +| Tno | varchar (20) | 否 | 教工编号(外码) | + +表(三)Score(成绩表) + +| 属性名 | 数据类型 | 可否为空 | 含义 | +| -------------- | ------------ | -------- | -------------- | +| Sno | varchar (20) | 否 | 学号(外码) | +| Cno | varchar (20) | 否 | 课程号(外码) | +| Degree | Decimal(4,1) | 可 | 成绩 | +| 主码:Sno+ Cno | | | | + +表(四)Teacher(教师表) + +| 属性名 | 数据类型 | 可否为空 | 含义 | +| --------- | ------------ | -------- | ---------------- | +| Tno | varchar (20) | 否 | 教工编号(主码) | +| Tname | varchar (20) | 否 | 教工姓名 | +| Tsex | varchar (20) | 否 | 教工性别 | +| Tbirthday | datetime | 可 | 教工出生年月 | +| Prof | varchar (20) | 可 | 职称 | +| Depart | varchar (20) | 否 | 教工所在部门 | + +```mysql +create database test03 charset utf8; + +use test03; + +CREATE TABLE `student` ( + `Sno` varchar(20) NOT NULL COMMENT '学号', + `Sname` varchar(20) NOT NULL COMMENT '学生姓名', + `Ssex` varchar(20) NOT NULL COMMENT '学生性别', + `Sbirthday` datetime DEFAULT NULL COMMENT '学生出生年月', + `Class` varchar(20) DEFAULT NULL COMMENT '学生所在班级', + PRIMARY KEY (`Sno`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +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'); + +CREATE TABLE `teacher` ( + `Tno` varchar(20) NOT NULL COMMENT '教工编号', + `Tname` varchar(20) NOT NULL COMMENT '教工姓名', + `Tsex` varchar(20) NOT NULL COMMENT '教工性别', + `Tbirthday` datetime DEFAULT NULL COMMENT '教工出生年月', + `Prof` varchar(20) DEFAULT NULL COMMENT '职称', + `Depart` varchar(20) NOT NULL COMMENT '教工所在部门', + PRIMARY KEY (`Tno`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +insert into teacher values +('804','李诚','男','1958-12-2','副教授','计算机系'), +('856','张旭','男','1969-3-12','讲师','电子工程系'), +('825','王萍','女','1972-5-5','助教','计算机系'), +('831','刘冰','女','1977-8-14','助教','电子工程系'); + +CREATE TABLE `course` ( + `Cno` varchar(20) NOT NULL COMMENT '课程号', + `Cname` varchar(20) NOT NULL COMMENT '课程名称', + `Tno` varchar(20) NOT NULL COMMENT '教工编号', + PRIMARY KEY (`Cno`), + KEY `Tno` (`Tno`), + CONSTRAINT `course_ibfk_1` FOREIGN KEY (`Tno`) REFERENCES `teacher` (`Tno`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +insert into course values +('3-105','计算机导论','825'), +('3-245','操作系统','804'), +('6-166','数字电路','856'), +('9-888','高等数学','831'); + +CREATE TABLE `score` ( + `Sno` varchar(20) NOT NULL COMMENT '学号', + `Cno` varchar(20) NOT NULL COMMENT '课程号', + `Degree` decimal(4,1) DEFAULT NULL COMMENT '成绩', + PRIMARY KEY (`Sno`,`Cno`), + KEY `Cno` (`Cno`), + CONSTRAINT `score_ibfk_1` FOREIGN KEY (`Cno`) REFERENCES `course` (`Cno`), + CONSTRAINT `score_ibfk_2` FOREIGN KEY (`Sno`) REFERENCES `student` (`Sno`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +insert into score values +('103','3-245',86), +('105','3-245',75), +('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); +``` + +表(一)Student + +| Sno | Sname | Ssex | Sbirthday | class | +| ---- | ----- | ---- | --------- | ----- | +| 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 | + +表(二)Course + +| Cno | Cname | Tno | +| ----- | ---------- | ---- | +| 3-105 | 计算机导论 | 825 | +| 3-245 | 操作系统 | 804 | +| 6-166 | 数字电路 | 856 | +| 9-888 | 高等数学 | 831 | + +表(三)Score + +| Sno | Cno | Degree | +| ---- | ----- | ------ | +| 103 | 3-245 | 86 | +| 105 | 3-245 | 75 | +| 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 | + +表(四)Teacher + +| Tno | Tname | Tsex | Tbirthday | Prof | Depart | +| ---- | ----- | ---- | --------- | ------ | ---------- | +| 804 | 李诚 | 男 | 1958-12-2 | 副教授 | 计算机系 | +| 856 | 张旭 | 男 | 1969-3-12 | 讲师 | 电子工程系 | +| 825 | 王萍 | 女 | 1972-5-5 | 助教 | 计算机系 | +| 831 | 刘冰 | 女 | 1977-8-14 | 助教 | 电子工程系 | + +3. **数据库中的数据**: + +-- 1,查询所有学生,都学了哪些课程,要显示学生信息和课程信息 + +```mysql +select sname,course.cname from student inner join score on student.sno=score.sno left join course on score.cno=course.cno; +``` + +-- 2,查询没有学生的教师的所有信息 + +```mysql +select Teacher.Tno,Tname,Tsex,Tbirthday,Prof,Depart from Teacher left join Course on Teacher.Tno = Course.Tno left join Score on Course.Cno = Score.Cno where Score.Sno is null; +``` + +4. ##### 查询: + +1.查询Score表中的最高分的学生学号和课程号。 + +```mysql +select sno,cno from score where degree=(select max(degree) from score); +``` + +2.查询所有学生的Sname、Cno和Degree列。 + +```mysql +select Sname,Cno,Degree from Student,Score where Student.Sno=Score.Sno; +``` + +3.查询所有学生的Sno、Cname和Degree列。 + +```mysql +select sno,cname,degree from course,score where course.cno = score.cno; +``` + +4.查询所有学生的Sname、Cname和Degree列。 + +```mysql +select sname,cname,degree from student,course,score where student.sno=score.sno and course.cno=score.cno; +``` + +5.查询“95033”班学生的平均分。 + +```mysql +select cno,avg(degree) from score where sno in (select sno from student where class='95031') group by cno; +``` + +6.查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。 + +```mysql +select * from score where cno='3-105' and degree>(select degree from score where sno='109' and cno='3-105'); +``` + +7.查询score中选学多门课程的同学中分数为非最高分成绩的记录。 + +```mysql +select * from Score a where Degree <(select MAX(degree) from Score b where a.Cno=b.Cno) and Sno in(select Sno from Score group by Sno having count(*)>1); +``` + +8.查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。 + +```mysql +select * from Student,Score where Student.Sno=Score.Sno and Score.Degree>(select Degree from Score where Cno='3-105' and Sno='109'); +``` + +9.查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。 + +```mysql +select sno,sname,sbirthday from student where sbirthday in (select sbirthday from student where sno='108'); +``` + +10.查询“张旭“教师任课的学生成绩。 + +```mysql +select Sname,Degree from Student,Score where Student.Sno=Score.Sno and Cno ='6-166'; +``` + +11.查询选修某课程的同学人数多于5人的教师姓名。 + +```mysql +Select * from teacher where tno=(Select tno from course where cno=(Select cno from score group by cno having count(*)>5)); +``` + +12.查询出“计算机系“教师所教课程的成绩表。 + +```mysql +select * from score where cno in(select cno from course where tno in(select tno from teacher where depart='计算机系')); +``` + +13.查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。 + +```mysql +select Tname,Prof from Teacher a where Prof not in(select Prof from Teacher b where a.Depart!=b.Depart); +``` + +14.查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。 + +```mysql +select * from score where cno='3-105' and degree>any(select degree from score where cno='3-245') order by degree desc; +``` + +15.查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree. + +```mysql +select * from score where cno='3-105' and degree>all(select degree from score where cno='3-245'); +``` + +16.查询成绩比该课程平均成绩低的同学的成绩表。 + +```mysql +select Sno,Cno,Degree from Score a where a.Degree<(select AVG(Degree) from Score b where a.Cno=b.Cno); +``` + +17.查询所有任课教师的Tname和Depart. + +```mysql +select Tname,Depart from Teacher where Tname in (select distinct Tname from Teacher,Course,Score where Teacher.Tno=Course.Tno and Course.Cno=Score.Cno); +``` + +18.查询所有未讲课的教师的Tname和Depart. + +```mysql +select Tname,Depart from Teacher where Tname not in (select distinct Tname from Teacher,Course,Score where Teacher.Tno=Course.Tno and Course.Cno=Score.Cno); +``` + +19.查询“男”教师及其所上的课程。 + +```mysql +select Tname,Cname from Teacher,Course where Tsex='男' and Teacher.Tno=Course.Tno; +``` + +20.查询最高分同学的Sno、Cno和Degree列。 + +```mysql +select sno,cno,degree from score where degree = (select max(degree) from score); +``` + +21.查询和“李军”同性别的所有同学的Sname. + +```mysql +select sname from student where ssex = (select ssex from student where sname = '李军'); +``` + +22.查询和“李军”同性别并同班的同学Sname. + +```mysql +select sname from student where ssex = (select ssex from student where sname = '李军') and class = (select class from student where sname = '李军'); +``` + +23.查询所有选修“计算机导论”课程的“男”同学的成绩表。 + +```mysql +select sname,ssex,degree from student s,course c,score sc where s.sno=sc.sno and sc.cno=c.cno and c.cname = '计算机导论' and s.ssex = '男'; +``` \ No newline at end of file diff --git "a/49 \346\235\216\350\210\222\346\261\266/20230309\344\275\234\344\270\232\345\222\214\345\244\247\344\275\234\344\270\232.md" "b/49 \346\235\216\350\210\222\346\261\266/20230309\344\275\234\344\270\232\345\222\214\345\244\247\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..12c1a1e411b362f6484fc6cf230dec17471fd383 --- /dev/null +++ "b/49 \346\235\216\350\210\222\346\261\266/20230309\344\275\234\344\270\232\345\222\214\345\244\247\344\275\234\344\270\232.md" @@ -0,0 +1,267 @@ +## 练习 + +```mysql +create database hh; + +use hh; + +create table ordertime( + orderid int primary key, + orderdate datetime +); + +insert into ordertime values +(1,'2008-01-12 00:00:00.000'), +(2,'2008-02-10 00:00:00.000'), +(3,'2008-02-15 00:00:00.000'), +(4,'2008-03-10 00:00:00.000'); + +create table item ( + itemid int(11) primary key, + orderid int, + itemtype varchar(10), + itemname varchar(10), + thenumber int(11), + themoney int(11) +); + +ALTER TABLE item CONVERT TO CHARACTER SET utf8; + +insert into item values +(1,1,'文具','笔',72,2), +(2,1,'文具','尺',10,1), +(3,1,'体育用品','篮球',1,56), +(4,2,'文具','笔',36,2), +(5,2,'文具','固体胶',20,3), +(6,2,'日常用品','透明胶',2,1), +(7,2,'体育用品','羽毛球',20,3), +(8,3,'文具','订书机',20,3), +(9,3,'文具','订书机',10,3), +(10,3,'文具','裁纸刀',5,5), +(11,4,'文具','笔',20,2), +(12,4,'文具','信纸',50,1), +(13,4,'日常用品','毛巾',4,5), +(14,4,'日常用品','透明胶',30,1), +(15,4,'体育用品','羽毛球',20,3); +``` + +1.查询所有的订单的订单的编号,订单日期,订购产品的类别和订购的产品名称,订购数量和订购单价 + +```mysql +select a.*,itemtype,itemname,thenumber,themoney from ordertime a right join item b on a.orderid=b.orderid; +``` + +2.查询订购数量大于50的订单的编号,订单日期,订购产品的类别和订购的产品名称 + +```mysql +select a.*,itemtype,itemname from ordertime a right join item b on a.orderid=b.orderid where thenumber>50; +``` + +3.查询所有的订单的订单的编号,订单日期,订购产品的类别和订购的产品名称,订购数量和订购单价以及订购总价 + +```mysql +select a.*,itemtype,itemname,thenumber,themoney,(thenumber*themoney) 订购总价 from ordertime a right join item b on a.orderid=b.orderid ; +``` + +4.查询单价大于等于5 或者 数量大于等于50的订单的订单的编号,订单日期,订购产品的类别和订购的产品名称,订购数量和订购单价以及订购总价 + +```mysql +select a.*,itemtype,itemname,thenumber,themoney,(thenumber*themoney) 订购总价 from ordertime a right join item b on a.orderid=b.orderid where themoney>=5 or thenumber>=50; +``` + +5.查询每个订单分别订购了几个产品 + +```mysql +select itemid 编号,thenumber 订购产品数 from item; +``` + +6.查询每个订单里的每个类别的产品分别订购了几次和总数量 + +```mysql +select orderid 订单编号,itemtype 产品类别,count(thenumber) 订购次数,sum(thenumber) 总数量 from item group by orderid,itemtype; +``` + + + +## 大作业 + +```mysql +create database xs charset utf8; + +use xs; +``` + +1. 根据前面提供的表结构和表数据,创建数据库并分别创建这张四张表;并插入相关数据。(提醒:外键请注意建表顺序和插入数据的顺序) (30分) + + ```mysql + create table author( + author_id int primary key comment '作家编号', + author_name varchar(20) unique not null comment '作家姓名', + credits int comment '积分', + vip_id varchar(20) not null comment '等级编号', + foreign key(vip_id) references vip(vip_id) + ); + + insert into author values + (1001,'朱逸群',600,'VIP02'), + (1002,'范建',8510,'VIP04'), + (1003,'史珍香',981,'VIP02'), + (1004,'范统',2364,'VIP02'), + (1005,'杜子腾',257,'VIP01'), + (1006,'刘产',678,'VIP02'), + (1007,'杜琦燕',438,'VIP03'); + + create table vip( + vip_id varchar(20) primary key comment '等级编号', + vip_name varchar(20) unique not null comment '等级名称' + ); + + insert into vip values + ('VIP01','青铜作家'), + ('VIP02','白银作家'), + ('VIP03','黄金作家'), + ('VIP04','钻石作家'); + + create table story( + story_id int primary key auto_increment comment '作品编号', + author_id int comment '作家编号', + type_id varchar(20) comment '类型编号', + story_name varchar(50) comment '作品名称', + views_number int comment '浏览量', + foreign key(author_id) references author(author_id), + foreign key(type_id) references type(type_id) + ); + + insert into story values + (1,1002,'L03','母猪产后与护理师的二三事',6541), + (2,1005,'L04','拖拉机大战蜘蛛侠',563), + (3,1003,'L01','这只小龙虾不正经',8754), + (4,1006,'L04','一个爹爹三个娃',36354), + (5,1006,'L01','皇上滚开本宫只劫财',3674), + (6,1005,'L05','给长城贴瓷砖的小太监',6541), + (7,1003,'L03','不科学御兽',1257), + (8,1005,'L01','镜面管理局',3216), + (9,1004,'L02','关于我成为灭魂师之后',1147), + (10,1004,'L05','公子别秀',2078); + + create table type( + type_id varchar(20) primary key comment '类型编号', + type_name varchar(20) unique not null comment '类型名称' + ); + + insert into type values + ('L01','玄幻'), + ('L02','奇幻'), + ('L03','武侠'), + ('L04','仙侠'), + ('L05','都市'); + ``` + +2. 将story 表中的story_name字段类型改成varchar(40) 。(2分) + + ```mysql + alter table story modify story_name varchar(40); + ``` + +3. 在author表中增加一个性别字段 字段名:author_sex,类型: char(10),要求默认值为'男'。 (3分) + + ```mysql + alter table author add author_sex char(10) default '男'; + ``` + +4. 将作家编号为1005、1007的作家性别改为'女' 。(2分) + + ```mysql + update author set author_sex='女' where author_id=1005 or author_id=1007; + ``` + +5. 作家杜子腾,写了一篇名为《拜登夸我很帅》的都市小说,有854个浏览量,请将这条信息插入到story表。(3分) + + ```mysql + insert into story values + (11,1005,'L05','拜登夸我很帅',854); + ``` + + 6. 《拖拉机大战蜘蛛侠》这篇小说,浏览量涨了100,请更新story表中的相关数据。(2分) + + ```mysql + update story set views_number=views_number+100 where story_name='拖拉机大战蜘蛛侠'; + ``` + +6. 请删除story表的中《皇上滚开本宫只劫财》这篇小说相关数据。(2分) + + ```mysql + delete from story where story_name='皇上滚开本宫只劫财'; + ``` + + 8. 查询 浏览量大于 8000的小说的作者编号和小说作品名称。(2分) + + ```mysql + select * from story where views_number>8000; + ``` + +7. 查询积分大于1000 并且会员等级高于vip03的作家所有信息。(3分) + + ```mysql + select * from author where credits>1000 and vip_id>'vip03'; + ``` + +8. 查询姓名以杜字开头的作家的姓名,积分和等级编号。(3分) + + ```mysql + select author_name,credits,vip_id from author where author_name like '杜%'; + ``` + +9. 查询积分在100、1000之间的作家信息,以积分降序排列。 (3分) + + ```mysql + select * from author where credits between 100 and 1000 order by credits desc; + ``` + +10. 查询出小说的总浏览量,最高浏览量,最小浏览量,平均浏览量,给字段用上中文别名。(3分) + + ```mysql + select sum(views_number) 总浏览量,max(views_number) 最高浏览量,min(views_number) 最小浏览量,avg(views_number) 平均浏览量 from story; + ``` + +11. 查询各种等级的作家的平均积分和作家数量,并对查询结果使用中文别名。(3分) + + ```mysql + select vip_id 作家等级,avg(credits) 平均积分,count(author_name) 作家数量 from author group by vip_id; + ``` + +12. 查询小说数量大于等于2的分类编号和小说数量。(4分) + + ```mysql + select type_id,count(type_id) 小说数量 from story where type_id>='L02' group by type_id; + ``` + +13. 查询所有小说中浏览量最少的书的作品编号、作品名称和类型编号、浏览量。(4分) + + ```mysql + select story_id,story_name,type_id,views_number from story where views_number = (select min(views_number) from story); + ``` + +14. 查询积分比刘产高的作者所有信息。(5分) + + ```mysql + select * from author where credits > (select credits from author where author_name='刘产'); + ``` + +15. 查询出哪些白银作家是没有写小说的,显示这些作家的姓名、等级名称。(8分) + + ```mysql + select author_name,vip_name from vip v right join author a on v.vip_id=a.vip_id left join story s on a.author_id=s.author_id where story_id is null and vip_name='白银作家'; + ``` + +16. 找出写过作品浏览量大于5000的作家的所有作品中浏览量不到1000的作品信息(8分) + + ```mysql + select * from story where author_id in (select author_id from story where views_number>5000) and views_number<1000; + ``` + +17. 查询所有小说的小说编号、小说名称、浏览量、分类名称、作者姓名、作者积分、作者等级名称,结果字段要用中文别名,并按浏览量降序排列,如果浏览量一样的,再按积分降序排列。(10分) + +```mysql +select a.author_id 小说编号,author_name 小说名称,views_number 浏览量,type_name 分类名称,author_name 作者姓名,credits 作者积分,vip_name 作者等级名称 from vip v right join author a on v.vip_id=a.vip_id right join story s on a.author_id=s.author_id left join type t on s.type_id=t.type_id order by views_number desc,credits desc ; +``` diff --git "a/49 \346\235\216\350\210\222\346\261\266/20230316 \347\254\254\345\205\255\347\273\204\344\275\234\344\270\232.md" "b/49 \346\235\216\350\210\222\346\261\266/20230316 \347\254\254\345\205\255\347\273\204\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..4f20d61991bd61f8fda6cae7f8134c54ca892827 --- /dev/null +++ "b/49 \346\235\216\350\210\222\346\261\266/20230316 \347\254\254\345\205\255\347\273\204\344\275\234\344\270\232.md" @@ -0,0 +1,60 @@ +```mysql +-- 创建数据库 +create database hhw charset utf8; +use hhw; +-- 创建表格 +create table `user`( +user_id int primary key, +user_name varchar(5), +user_tel varchar(11), +ordertime date +); +create table `order`( +order_id int, +uesr_id int, +type varchar(10), +food varchar(10), +number int, +price int, +foreign key (uesr_id) references `user` (user_id) +); +-- 插入数据 +insert into `user` values +(1,'张三','19865645691','2023-3-13'), +(2,'李四','12345675691','2023-3-13'), +(3,'王五','12895678901','2023-3-13'), +(4,'老六','12345678691','2023-3-14'), +(5,'小七','18945678031',null), +(6,'老八','19345678561','2023-3-16'), +(7,'朱九','15845679911',null); +insert into `order` values +(1,1,'快餐','肯德基全家桶',1,50), +(2,1,'快餐','可乐',4,20), +(3,6,'饮料','柠檬水',2,16), +(4,2,'米饭','鱼香肉丝盖饭',5,60), +(5,2,'饮料','珍珠奶茶',3,22), +(6,3,'粉面类','螺蛳粉',4,28), +(7,4,'粉面类','凉拌面',1,10); +-- 根据上表所给信息完成下列题目: +-- 1.在用户表(user)新增一个性别字段user_sex,数据类型为char。 +ALTER TABLE `user` add user_sex char; +-- 2.由于顾客3退单,请把此订单删除。 +DELETE +FROM `order` WHERE order_id = 3; +-- 3.老八的电话号码换新了,请将他的号码更新为8888888888。 +UPDATE `user` SET user_tel = 8888888888 WHERE user_name = '老八'; +-- 4.查询order表里的最高金额和总金额。 +SELECT max( price ) 最高金额, sum( price ) 总金额 FROM `order`; +-- 5.查询每个顾客分别订购了几个类别。 +SELECT DISTINCT type, user_name FROM `user` a LEFT JOIN `order` b ON a.user_id = b.uesr_id WHERE b.uesr_id IS NOT NULL ORDER BY type; +-- 6.查询饮料的总金额 +SELECT sum( price ) FROM `order` WHERE type = '饮料'; +-- 7.查询订单表(order)里的订单号,类别(type),食物(food). +select order_id,type,food from `order`; +-- 8.查询没吃饭的人的所有信息 +SELECT a.* FROM `user` a LEFT JOIN `order` b ON a.user_id = b.uesr_id WHERE b.uesr_id IS NULL; +-- 9.查询姓老的人的全部信息及订单信息 +SELECT * FROM `user` a LEFT JOIN `order` b ON a.user_id = b.uesr_id WHERE a.user_name LIKE '老%'; +-- 10.查询总金额大于20的订单里最大值的用户信息,使用降序排列 +SELECT a.* FROM `user` a RIGHT JOIN `order` b ON a.user_id = b.uesr_id WHERE b.price > 20 and price=(SELECT max(price) from `order`); +```