您的位置:首页 > 数据库 > MySQL

课堂笔记--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函数中的一种。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  join math date mysql null hex