课堂笔记--Mysql
2011-09-13 21:47
537 查看
连接的相关介绍
多表连接
多张表连接查询, 一张表外键引用另外一张表, 另外一张表再引用其他表.例如: 员工表引用部门, 部门表引用城市表. 这时如果想根据员工查城市, 或者根据城市查员工就需要将三张表连接查询
准备工作:
创建城市表, id主键自动生成, 带有名称
插入两条记录, 北京和上海
在部门表添加city_id, 外键引用城市表的id
将开发部的地址改为北京, 市场部的地址改为上海
自连接
自己和自己连接, 当前表的外键引用自己的主键.例如: 员工的经理也是员工, 应该在员工表中添加一列经理id. 之后添加一个外键, 引用员工表的主键.
准备工作:
在员工表中添加manager_id, 外键引用员工表id
插入赵六, 孙七. 分别属于开发部和市场部.
将张三和李四的经理设置为赵六, 王五经理设置为孙七.
内连接、左外连接、右外连接(SQL99)
1. 内连接
之前我们使用逗号和where子句进行的连接就是内连接. 标准语法应使用 inner join 和 on, 例如:
select e.name,d.name from employee e,department d where e.department_id=d.id;
select e.name,d.name from employee e inner join department d on e.department_id=d.id;
内连接会将两张表完全匹配连接条件的记录查询出来, 不满足的不会显示
2. 左外连接
使用 left outer join 和 on 关键字进行连接查询, 这时左表中不满足条件的记录也会被查询出来
例如: 查询所有员工的部门, 要将没有部门的周八查询出来. 这时需要查询出员工表中所有记录, 即使不满足连接条件, 周八也要显示.
3. 右外连接
使用 right outer join 和 on 关键字进行连接查询, 这时右表中不满足条件的记录也会被查询出来
例如: 查询每个部门下都有哪些员工, 要将没有员工的财务部显示出来.
4. 全外连接
MySql不支持全外连接full outer join, 可以使用union distinct来实现.
查询及连接语句的应用
一、基本查询
1,选择列显示出来
select 列名1,列名2...
from 表名;
select sid,sname,ssex,sbrithday
from xs;
显示sid,sname,ssex,sbrithday这几列、
select * from 表名;显示所有的列
select sid as id,sname as name,ssex as sex,sbrithday as brithday
from xs;显示时显示的是as后边的起的别名,但是源数据库不变
起别名时AS可以省略
不会改变数据库中的值
<2>查询计算列
select sname,学分,学分+10学 as 提高后的学分
from xs;
<3>消除查询结果中的重复行
select distinct 列名,列名
from 表名;
多列或是一列的重复值只显示一次
DISTINCT :
注意事项
*可以替代列名, 表示所有列, 但是通常我们为了提高代码的可读性, 不使用*
DISTINCT为过滤重复记录
如果DISTINCT后面跟多列, 是过滤掉多列合并之后的重复
练习:
查询employee表中所有记录
select id,username,gender,birthday,position,salary,resume from user;
查询employee表中所有人的薪水
select username,salary from user;
查询employee表中包含哪些岗位
<4>替换查询结果中的数据
select sname,sid,
case
when statol<50 then'不及格'
when statol>=50 and statol<60 then'及格'
when statol>=60 then'优秀'
end
from xs;
当学分小于50就显示不及格,大于50并小于6显示及格,大于60显示优秀。
<5>聚合函数,通常和后面要将group up
select max(列名),min(列名)
from 表名;
一列中的最大最小值的查找
max(数值型列)求这一列的最大值
mix(数值型列)求这一列的最小值
avg(数值型列)求这一列的平均值
sum(数值型列)求这一列的和
count(列)求这一列多少次记录会忽略空值
count(*)表中的记录行数
count(distinct 指定某一列)指定列的取值去空值,去掉重复后的记录
COUNT函数
注意事项
COUNT(列名)的方式是统计指定列中有多少条记录, 不包括值为NULL的
COUNT(*)则是统计表中有多少条数据
COUNT(DISTINCT 列名) 统计不重复的记录数
如果加上WHERE子句, 则是统计满足条件的记录
练习
统计student表中有多少条记录
select count(*) from student;
统计学生语文成绩大于80的有多少人
select count(*) from student where chinese>80;
统计总分大于250的有多少人
select count(*) from student where english+math+chinese>250;
统计参加英语考试的有多少人
select count(english) from student;
SUM函数
注意事项
计算指定列中所有记录的和, 如果有WHERE子句则计算满足条件的记录
练习
计算所有学生的数学成绩总和
select sum(math) from student;
显示所有学生的语文成绩总和, 数学成绩总和, 英语成绩总和
select sum(chinese),sum(math),sum(english) from student;
计算所有学生的分数总和
select sum(chinese)+sum(math)+sum(english) from student;
统计英语平均分
select sum(english)/count(*) from student;
select sum(english)/count(english) from student;
AVG函数
注意事项
计算指定列的平均值, 如果有WHERE子句, 则计算满足条件的记录
AVG()统计平均数不包含NULL值
练习
计算英语平均分
select avg(english) from student;
计算总分平均分, MySQL不支持组函数嵌套使用.
select sum(english+math+chinese)/count(*) from student;
MAX / MIN函数
语法
注意事项
获取指定列最高/最低值, NULL不参与统计
练习
统计总分最高分和最低分
select max(english+math+chinese),min(english+math+chinese) from student;
<6>选择运算--where
select * from xs
where statol>45;显示表中学分大于45的学生显示出来
WHERE
WHERE子句中的运算符
比较运算符 | >, <, >=, <=, =, <> | 注意不等于和Java中不同, 是<> |
BETWEEN ... AN 4000 D ... | 某一区间内的值, 从 ... 到 ... | |
IN(列表) | 在列表之中, 例: in(1,2,3) 代表1或2或3 | |
LIKE(表达式) | 模糊查询, %代表多个字符, _代表单个字符 | |
IS NULL | 判断是否为NULL | |
逻辑运算符 | AND && | 与, 两边都为TRUE结果为TRUE |
OR || | 或, 一边为TRUE结果就为TRUE | |
NOT ! | 非, 将表达式结果取反 |
查询英语分数在80-90分之间的
select name,english from student where english>=80 and english<=90;
查询语文分数为81,82,83的学生
select name,english from student where english in(80,90,82);
查询所有姓张的学生的成绩
select name,english,math,chinese from student where name like '张%';
查询除了姓张和姓李的学生总分
select name,english,math,chinese
from student
where name not like '张%'
and name not like '李%';
select name,english,math,chinese
from student
where name like '张%'
or name like '李%';
ORDER BY
ordeer by对结果查询进行排序select 列名一,列名二。。。
from 表名
where 查询条件
order by 列名1【,列名2.。。。】[asc(升序,可以省略)desc(降序,不可省略)]
注意事项
ORDER BY 指定排序的列名可以是表中的列名, 也可以是SELECT语句后面起的别名
ASC为升序, DESC为降序
ORDER BY应在查询语句的结尾
练习
对数学成绩排序后输出
select name,math from student order by math;
查询总分, 从高到低显示
select name '姓名',chinese+math+english '总分' from student order by 总分 desc;
选择所有姓张的学生的英语成绩, 并从高到低排序
select name,english from student where name like '张%' order by english desc;
查询学生成绩, 按照语文从高到低排序, 如果语文相同, 按照英语从高到低排序
select * from student order by chinese desc,english desc;
select 学号,姓名,出生时间
from xs
order by 出生时间 desc;
select 学号,课程号,成绩
from xs
order by 课程号 asc ,成绩 desc; (先按课程号排序,在课程号相同的时候再按成绩排序)
limit子句:限制的是显示的记录的行数,一般是和order by子句一起用
limit[位移量]显示记录的行数
select 学号,课程号,成绩
from xs
where 课程号=‘101’
order by 成绩 desc
limit 3;显示前几条的行数
select 学号,课程号,成绩
from xs
where 课程号=‘101’
order by 成绩 desc
limit 3,3;
GROUP BY(重点)
语法SELECT 列名 FROM 表名 GROUP BY 列名 [HAVING 条件语句]
注意事项
按照某列归类
HAVING和WHERE类似, 但HAVING是作用于组, 其中可以使用组函数
SELECT列表中未包含在组函数中的列名, 只能是GROUP BY中的列名
HAVING中可以使用组函数, WHERE不能.
练习
导入order.sql
对订单表归类, 显示购买过哪些商品
select product from orders group by product;
select distinct product from orders;
对订单表归类, 显示购买过哪些商品, 并显示每种购买了几个, 以及总价
select product,count(product),sum(price) from orders group by product;
查询总价大于5000的商品有哪几类
select product,count(product),sum(price) sum_price from orders group by product having sum_price>5000;
二 、高级查询:多表连接查询、子查询、分组查询
1、 多表查询
eg: 姓名 课程名 成绩
xs course grade
(1)全连接 ----不是标准的Mysql语句
select 列名一,列名二,。。。
from 表名一,表名二。。。
where 表名1.某一列=表名2.某一列列名
select xs.学号,姓名,课程号,成绩
from xs,course
where xs.学号=course.学号;
查看:学号、课程号、学时
select 学号,姓名,course.课程号,学时
from xs,course
where xs.课程号=course.课程号and ··=··;
(2)标准的Mysql语句,推荐使用
有内连接,有外连接、自然连接、交叉连接
1)内连接:from [inner]join 表二 on 连接条件
select 列名表
from 表名一join表名二
on 连接条件
select 学号,姓名,course.课程号,学时
from xs join course
where xs.课程号=course.课程号and ··=··;
select 列名表
from 表名一join表名二
using(学号);
2)外连接:包含来自一张表所有的记录行和另一张的匹配记录行
左外链接
右外链接
查询:所有的学生信息,所有的学号姓名以及所选课程的课程号、得分
select xs.学号,姓名,课程号,成绩
from xs left outer join course
on x.学号=··.学号;
select xs.学号,姓名,课程号,成绩
from xs left right join course
on x.学号=··.学号;
3)自然连接
natural join 自然内连接
natural left join
natural right join
select 列名表
from 表名一 naturaljoin表名二;
交叉连接--笛尔卡机
select xs.学号,姓名,课程号,成绩
from xs cross join course
on xs.学号=course.学号
product 、smaller、product_sall
select p.productid,productname,quantily
from product p join product_sall ps
on p.productid=ps.productid
from子句中给表起别名,这个表都 别名只在当前的select语句中有效,并且一旦给表起名,改select语句的其他子句如果要使用表名的话一定要用别名。
2、嵌套查询
子查询一般都可以写成多表连接查询
(1)xs_kc kc
select 学号,课程号
from xs_kc natural join kc
where 课程名=‘计算机基础’;
第一种思路:
select 学号
from xs_kc
where 课程号=(
select 课程号
from kc
where 课程号=‘计算机基础’
)
第一步:执行子查询
第二部:执行外部查询,外部查询的条件是依赖于子查询的
查询:所有成绩比平均成绩高的学生的学号和课程号
select 学号,课程号
from xs_kc
where 成绩>(
select avg(成绩)
from xs_kc
)
子查询只做一次75.2
(2)子查询的结果不是单列,多行
xs;学号,姓名
xs_kc :学号、课程号
select 姓名
from xs join xs_kc
on xs。学号=xs_kc.学号
where 课程号=‘206’;
Mysql函数的应用
时间函数
注意date, datetime, timestamp之间的区别ADDTIME(原时间, 增加值) 在某个时间上增加一段时间
select addtime('18:23:01', '01:01:01');
select addtime(now(),'3:0:0');
CURRENT_DATE() 当前日期
select current_date();
CURRENT_TIME() 当前时间
select current_time();
CURRENT_TIMESTAMP() 当前时间戳
select current_timestamp();
DATE(时间) 返回制定时间的日期部分
select date('2011-02-14 18:00:00');
DATE_ADD(日期,INTERVAL 增加值 类型) 在指定日期上对某个字段增加
select date_add('2011-02-14 23:00:00', interval 10 month);
DATE_SUB(日期,INTERVAL 减少值 类型) 在指定日期上对某个字段减少
select date_sub('2011-02-14 23:00:00', interval 1 year);
DATEDIFF(日期1, 日期2) 计算两个日期之间的差值
select datediff('2000-02-14', '2001-02-14');
NOW() 当前时间
select now();
YEAR|MONTH|DATE|HOUR|MINUTE|SECOND(时间) 获取指定时间的某个字段
select year('2011-02-14 23:00:00');
select hour('2011-02-14 23:00:00');
字符串函数
CHARSET(字符串) 返回字符串字符集select charset(name) from student;
CONCAT(字符串1[, 字符串2]... ) 连接字符串
select concat('aaa', 'bbb', 'ccc');
INSTR(字符串, 子字符串) 查找子字符串出现位置, 注意序号从1开始
select instr('abc', 'a');
UCASE(字符串) 将字符串转为大写
select ucase('aBc');
LCASE(字符串) 将字符串转为小写
select lcase('aBc');
LEFT(字符串, 长度) 从字符串左边取指定长度个字符
select left('aBc',2);
LENGTH(字符串) 计算字符串长度
select length('aBc');
REPLACE(字符串, 搜索字符串, 替换字符串) 将字符串中指定字符串替换为其他字符串
select replace('abbcbbd', 'bb', 'ee');
STRCMP(字符串1, 字符串2) 逐个字符比较两个字符串, 如果是包含关系, 则返回长度差值
select strcmp('abcc', 'abde');
select strcmp('abc', 'ab');
SUBSTRING(字符串, 开始坐标[, 个数]) 从字符串中截取
select substring('abcdef', 3);
select substring('abcdef', 3, 2);
LTRIM(字符串) 去掉左边空白
select ltrim(' abc ');
select concat('--', ltrim(' abc '), '--');
RTRIM(字符串) 去掉右边空白
select concat('--', rtrim(' abc '), '--');
TRIM(字符串) 去掉左右两边空白
select concat('--', trim(' abc '), '--');
数学函数
ABS(数字) 求绝对值select abs(10);
select abs(-10);
BIN(十进制数) 将十进制转换为二进制
select bin(5);
HEX(十进制数) 将十进制转换为十六进制
select hex(10);
CONV(数字, 原进制, 目标进制) 转换进制
select conv(12, 10, 16);
select conv(12, 10, 2);
select conv(12, 16, 2);
CEILING(小数) 向上取整
select ceiling(3.4);
FLOOR(小数) 向下取整
select floor(3.4);
ROUND(小数) 四舍五入
select round(3.4);
select round(3.5);
FORMAT(小数, 保留位数) 保留小数位
select format(3.1415926, 2);
LEAST(值,值[,值]...) 取最小值
select least(1,2,3,4);
select least('a', 'b', 'c', 'd');
GREATEST(值,值[,值]...) 取最大值
select greatest(1,2,3,4);
select greatest('a', 'b', 'c', 'd');
MOD(数字, 数字) 取余
select mod(3,2);
select 3%2;
RAND() 生成随机数, 14位小数, 0 <= n <= 1
select rand();
上面提到的聚合函数也是Mysql函数中的一种。
相关文章推荐
- MYSQL课堂笔记
- MySql课堂笔记
- 9-13课堂笔记MySQL
- mysql 事务分析小笔记--01
- MySQL服务维护笔记(转)
- Kettle学习笔记一 :MySQL到Postgres导入数据且发送日志邮件
- MySQL学习笔记——MySQL服务器的连接监听情况进行控制
- #实践笔记#Ubuntu配置Apache+PHP+MySQL
- MySQL学习笔记_01_MySQL中char和varchar的本质区别
- 【学习笔记】mysql 快速批量导入测试数据
- MySQL学习笔记 2:约束、修改数据表和操作数据表中的记录
- Flask+Mysql搭建网站之其他笔记
- 2018.3.23课堂笔记
- PHP燕十八 课堂笔记------递归 无限极分类
- Java学习笔记——JDBC之与数据库MySQL的连接以及增删改查等操作
- mysql5.6 linux下安装笔记
- MySQL入门笔记 —— 020 from型子查询
- 马哥学习笔记十四——MySQL进阶之数据类型和sql模型
- MySQL学习笔记2:数据库的基本操作
- JAVA的面向对象编程--课堂笔记