一、单表查询
1、source sql文件
set names gbk; //支持输入中文
将上述sql语句复制到txt中,将文件名改为xx.sql,文件另存为字符集是ANSI。存储到e:work
在mysql命令行输入:source e:/work/xx.sql;
source C:/Users/mystu.sql;
2、distinct去掉重复(对整条记录去重复)
select distinct 列1,列2 from 表名
mysql> select distinct job from emp; #查询员工的工作种类(去重复)
+-----------+
| job |
+-----------+
| 开发 |
| CLERK |
| SALESMAN |
| MANAGER |
| ANALYST |
| PRESIDENT |
+-----------+
mysql> select distinct deptno,job from emp; #查询每个部门的工作种类(组合)
+--------+-----------+
| deptno | job |
+--------+-----------+
| 1 | 开发 |
| 2 | 开发 |
| 20 | CLERK |
| 30 | SALESMAN |
| 20 | MANAGER |
| 30 | MANAGER |
| 20 | ANALYST |
| 20 | PRESIDENT |
| 30 | CLERK |
| 10 | CLERK |
+--------+-----------+
3、 增加算术运算符
例:将stu表中的age增加1
select age,age+1 from stu;
+------+-------+
| age | age+1 |
+------+-------+
| 20 | 21 |
| 23 | 24 |
| 23 | 24 |
| 32 | 33 |
| 23 | 24 |
| 23 | 24 |
| 21 | 22 |
| NULL | NULL |
+------+-------+
注:
null和任何数计算,结果都是null
ifnulll(表达式,值):如果表达式为null,返回值。不为空,返回表达式。
#如果age值不为空将age返回参与运算,如果为空返回0运算
select age,ifnull(age,0)+1 from stu;
+------+-----------------+
| age | ifnull(age,0)+1 |
+------+-----------------+
| 20 | 21 |
| 23 | 24 |
| 23 | 24 |
| 32 | 33 |
| 23 | 24 |
| 23 | 24 |
| 21 | 22 |
| NULL | 1 |
+------+-----------------+
8 rows in set (0.00 sec)
4、查询where(条件)
where 字段名 =、比较 值;
例:(1)查询所有经理的编号
(2)查询职位为salesman的员工编号,job职位,入职日期
(3)查询所有经理的编号
(4)查询职位为SALESMAN的员工编号、职位、入职日期
select empno from emp where job = 'manager';
select empno,job,hiredate from emp where job = "SALESMAN";
select ename,hiredate from emp where hiredate < '1985-12-31'; #时间字符串加上单引号或者双引号
select ename,deptno from emp where deptno != 10;
5、查询where in
此条件in()相当于 or 的关系[id在in()括号集合里的所有记录。相当于id=30 or id=32 or id=34 or id=36 or id=38;]
例:(1)查询工号为20,30的员工
(2)查询job 为 CLERK|SALESMAN|MANAGER 的员工
select * from emp where deptno in(20,30);
select * from emp where job in('CLERK','SALESMAN','MANAGER');
6、 查询where not in
not in ()的关系相当于 and
select * from stu where age not in(20,21);
等价于:select * from stu where age!=20 and age!=21;
7、模糊查询——where like
(1)模糊查询(like)---部分匹配
%:可以匹配0个或多个字符
_:可以匹配一个字符
(2)模糊查询(not like)---不匹配
%:可以匹配0个或多个字符
_:可以匹配一个字符
(3)转义:利用“\”转义,这时候\后面的字符转成本来的含义
select * from emp where ename like '%\_%'; -- 姓名中包含下划线_
练习:
-- 查询名字以 "S"开头的员工
-- 查询名字中包含 "S"的员工
-- 查询员工名字第二个字符是"O"的员工
-- 查询名字中带"_"的员工
-- 查询名字中不包括'W'的员工
select * from emp where ename like "S%";
select * from emp where ename like "%S%";
select * from emp where ename like "_o%";
select ename from emp where ename like '%\_%';
select ename from emp where ename not like '%w%';
7、满足一个条件的记录——where or
id满足任何一个条件的记录。or等价|
满足所有条件的记录——where and
练习:(1)查询部门编号为10或者20的员工姓名,部门编号
(2)查询20部门,并且job是'CLERK'的员工
(3)查询工资既不等于2000也不等于3000的员工
select ename,deptno from emp where deptno=10 or deptno=20;
select * from emp where deptno=20 and job='CLERK';
select * from emp where sal != 2000 and sal != 3000;
8、区间——where between and
例子:查询月薪在3000到5000的员工姓名,月薪。
Select ename 员工姓名,(sal+ifnull(comm,0)) 月薪
9、排序——order by
按照某一个列进行排序,默认asc升序,desc降序,列名可以用select后面列的序号
练习:(1)查询员工信息,按照部门编号升序排,在部门内部按照工资升序排
(2)查询员工信息,按照部门编号降序排,在部门内部按照工资升序排
select * from emp order by deptno,sal;
select * from emp order by deptno desc,sal asc;
10、分组——group by
(1)GROUP BY子句指定要分组的列,通过GROUP BY子句可将表中满足WHERE条件的记录按照指定的列划分成若干个小组;
(2)GROUP BY子句中可以按照多个列分组。
(3)having子句是对分组后的信息进行筛选。
(4)Select 后面可以写分组的列名,别的都不能出现。 可写统计函数有5个,sum, avg, max, min, count. 如果写非分组列,取出的值不一定,可能是组里面第一条记录。
(5)sql语句分组以后的执行顺序如下,如果是分组条件筛选必须在having中,不能在where中。别名可以在order by 中使用不能在分组中使用(Mysql支持,Oracle不支持)。
(6)count(*)获取每组记录数,count(列名)获取列不为空符合条件记录数
(7) 语句的执行顺序如下:
from --where--group by--having--select--order by--limit
Select ….. 5.
From ….. 1.
Where …… 2.
Group by ….. 3.
having …. 4.
Order by …. 6
Limit … 7
1)如果条件必须是分组后才能得出,必须放在having后面。比如count(*)>3必须放在having后面,不能放在where后面,因为不分组,不知道每组有多少人。
2)如果条件和分组没有关系,可以放在where后面,也可以放在having后面。比如age>21,不分组也知道age是否大于21,所以可以放在where后面
--写法错误,因为先执行where还没有分组,无法统计每组人数
select age,count(*) from stu where count(*)>3 group by age ;
--错误根据执行顺序,先执行where还没有分组,没有办法算平均年龄。
select avg(age) 平均年龄,sex from stu where avg(age)>23 group by sex ;
select avg(age) 平均年龄,sex from stu group by sex having avg(age)>23;--正确
--条件不是分组后得出
mysql> select age,count(*) from stu where age>21 group by age;
(8)group by 列名 asc/desc,默认是asc升序。对要查询的列进行排序
(9)where和having条件,如果条件能写在where中尽量写在where,速度快。
例题:获取年龄大于21岁每组有多少人
select age,count(*) from stu group by age having age >21;
+------+----------+
| age | count(*) |
+------+----------+
| 23 | 4 |
| 32 | 1 |
+------+----------+
select age,count(*) from stu where age>21 group by age desc;
+------+----------+
| age | count(*) |
+------+----------+
| 32 | 1 |
| 23 | 4 |
+------+----------+
例题:(1)查询按年龄分组,每个年龄人数大于3的
(2)查询按性别分组,平均年龄大于23的
(3)统计stu表中男女各有多少人
(4)根据部门编号统计平均工资
(5)统计各部门下不同职位的平均工资
(6)求员工数大于2的部门编号和部门人数
(7)查询每个部门最高工资大于2900的部门编号,最高工资
(8)求各部门中工资大于2000的员工的部门编号,平均工资
(9)求平均工资大于1500的部门编号和平均工资
(10)查询每个部门每个岗位的工资总和
select age,count(*) from stu group by age having count(*) > 3;
+------+----------+
| age | count(*) |
+------+----------+
| 23 | 4 |
+------+----------+
select avg(age) 平均年龄,sex from stu group by sex having avg(age)>23;
+----------+------+
| 平均年龄 | sex |
+----------+------+
| 24.5000 | 男 |
+----------+------+
select sex,count(*) from stu group by sex;
+------+----------+
| sex | count(*) |
+------+----------+
| 女 | 4 |
| 男 | 4 |
+------+----------+
select deptno,avg(sal) from emp group by deptno;
select job,avg(sal) from emp group by job;
select deptno,job,avg(sal) from emp group by deptno,job;
select deptno,count(*) from emp group by deptno having count(*) > 2;
select deptno,max(sal) from emp group by deptno having sal > 2900;
select deptno,sum(sal) from emp where job != 'SALESMAN' group by deptno having sum(sal) > 1000;
select deptno,avg(sal) from emp where sal > 2000 group by deptno;
select deptno,job,sum(sal) from emp group by deptno,job;
11、limit 0,n——获取前n条数据,用在分页
使用select语句时,经常要返回前几条或者中间某几行记录,可以使用关键字limit
语法格式如下:
SELECT [DISTINCT] { * | 列名|表达式[别名][,...]}
FROM 表名
[WHERE 条件]
[ORDER BY {列名|表达式|列别名|列序号} [ASC|DESC],…]
[limit start, length ] 当start=0时,start可以省略
页数page,每页显示条数n条
select * from 表名 limit (page-1)*n,n
每页显示3条记录,分页获取记录
1页1-3条:select * from stu limit 0,3;
2页4-6条select * from stu limit 3,3;
3页7-9条select * from stu limit 6,3;
练习:(1)查询入职日期最早的前5名员工姓名,入职日期
(2)查询工作在30号部门并且入职日期最早的前2名员工姓名,入职日期
select ename,hiredate from emp order by hiredate limit 5;
+--------+------------+
| ename | hiredate |
+--------+------------+
| SMITH | 1980-12-17 |
| aLLEN | 1981-02-20 |
| WARD | 1981-02-22 |
| J_ONES | 1981-04-02 |
| BLAKE | 1981-05-01 |
+--------+------------+
select ename,hiredate from emp where deptno = 30 order by hiredate limit 0,2;
+-------+------------+
| ename | hiredate |
+-------+------------+
| aLLEN | 1981-02-20 |
| WARD | 1981-02-22 |
+-------+------------+
12、is null 和 is not null
-- 查询奖金为null的员工
select * from emp where comm is null;
-- 查询奖金不为null的员工
select * from emp where comm is not null;
二、常用函数
(一)单行函数
1、数值型函数
ABS(x):返回x的绝对值;
SQRT(x):返回非负数x的平方根;
PI():返回圆周率;
MOD(x,y)或%:返回x被y除的余数;
CEIL(x)、CEILING(x):返回大于或者等于x的最小整数值;(向上取整)
FLOOR(x):返回小于或者等于x的最大整数值;(向下取整)
ROUND(x,y):返回保留小数点后面y位,四舍五入的整数;(四舍五入)
TRUNCATE(x,y):返回被舍弃的小数点后y位的数字x;
RAND():每次产生不同的随机数;
SIGN(x):返回参数的符号;
select abs(-2),sqrt(2),pi(),mod(5,3),ceil(3.5),floor(3.5),round(3.6),truncate(3.14,0),rand(),sign(6);
+---------+--------------------+----------+----------+-----------+------------+------------+------------------+--------------------+---------+
| abs(-2) | sqrt(2) | pi() | mod(5,3) | ceil(3.5) | floor(3.5) | round(3.6) | truncate(3.14,0) | rand() | sign(6) |
+---------+--------------------+----------+----------+-----------+------------+------------+------------------+--------------------+---------+
| 2 | 1.4142135623730951 | 3.141593 | 2 | 4 | 3 | 4 | 3 | 0.6271426143377485 | 1 |
+---------+--------------------+----------+----------+-----------+------------+------------+------------------+--------------------+---------+
--写一个查询,分别计算100.456 四舍五入到小数点后第2位,第1位,整数位的值
select round(100.456,2),round(100.456,1),round(100.456,0);
+------------------+------------------+------------------+
| round(100.456,2) | round(100.456,1) | round(100.456,0) |
+------------------+------------------+------------------+
| 100.46 | 100.5 | 100 |
+------------------+------------------+------------------+
--写一个查询,分别计算100.456 从小数点后第2位,第1位,整数位截断的值
select TRUNCATE(100.456,2),TRUNCATE(100.456,1),TRUNCATE(100.456,0);
+---------------------+---------------------+---------------------+
| TRUNCATE(100.456,2) | TRUNCATE(100.456,1) | TRUNCATE(100.456,0) |
+---------------------+---------------------+---------------------+
| 100.45 | 100.4 | 100 |
+---------------------+---------------------+---------------------+
2、字符串:
(1)CHAR_LENGTH(str):返回字符串str的所包含字符个数;--中文当做一个字符
select char_length('I love china'),char_length('I love 中国');--12 9
(2)LENGTH(str):返回字符串str的长度;---一个汉字当做两个字符
select length('I love china'),length('I love 中国');--12 11
(3)CONCAT(s1,s2,...):字符串连接
select concat('I','love','China');
(4)CONCAT_WS(x,s1,s2,…):字符串连接, x是其它参数的分隔符;
select concat_ws('_','I','love','China');
(5)INSERT(s1,x,len,s2) :返回字符串s1,s1中从下标x位置下标从1开始,用s2替换后面len个字符
select insert('I love china',8,0,'my ');-- I love my china
select insert('I love china',8,2,'my ');-- I love my ina
(6)LOWER (str)|LCASE (str):将字符串全部转换成小写字母;
select LOWER(ENAME) FROM EMP;
--------------+
| LOWER(ENAME) |
+--------------+
| adams |
| allen |
| blake |
+--------------+
(7)UPPER(str)|UCASE(str):将字符串全部转换成大写字母;
(8)LEFT(s,n):返回最左边指定长度的字符;
select ename,left(ename,2) from emp;
+------------+---------------+
| ename | left(ename,2) |
+------------+---------------+
| ADAMS | AD |
| aLLEN | aL |
| BLAKE | BL |
+------------+---------------+
(9)RIGHT(s,n):返回最右边指定长度的字符;
(10)LPAD(s1,len,s2)| RPAD(s1,len,s2) :将字符串s2填充到s1的左边或右边,直到len长度
select ename,lpad(ename,10,'*') from emp;
+------------+--------------------+
| ename | lpad(ename,10,'*') |
+------------+--------------------+
| ADAMS | *****ADAMS |
| aLLEN | *****aLLEN |
| BLAKE | *****BLAKE |
| CLARK | *****CLARK |
| FORD | ******FORD |
| JAMES | *****JAMES |
+------------+--------------------+
(11)TRIM(s1 FROM s)|LTRIM(s)|RTRIM(s):删除空格函数;
(12)SUBSTRING(s,n,len):获取子串函数;数据库中,首字符对应的下标是1. n: 起始位置
select ename,SUBSTRING(ename,1,3),substr(ename,1,3) from emp;
+------------+----------------------+-------------------+
| ename | SUBSTRING(ename,1,3) | substr(ename,1,3) |
+------------+----------------------+-------------------+
| ADAMS | ADA | ADA |
| aLLEN | aLL | aLL |
| BLAKE | BLA | BLA |
+------------+----------------------+-------------------+
练习:
1. 求I love china 中国的长度
2. 把”I”, “love” “China”拼接在一起
3. 把ename , “_”, job 拼接在一起
4. 把”5000”有“*”左填充到8位,****5000
5. “ abc def ”去左右空格
6. 截取”I love china” 的前三位字符
select length('I love china 中国');
+-----------------------------+
| length('I love china 中国') |
+-----------------------------+
| 17 |
+-----------------------------+
select concat("I","love","china");
+----------------------------+
| concat("I","love","china") |
+----------------------------+
| Ilovechina |
+----------------------------+
select concat_ws('_',ename,job) from emp ;
+--------------------------+
| concat_ws('_',ename,job) |
+--------------------------+
| SMITH_CLERK |
| aLLEN_SALESMAN |
| WARD_SALESMAN |
| J_ONES_MANAGER |
| MARTIN_SALESMAN |
| BLAKE_MANAGER |
+--------------------------+
select lpad(5000,8,'*');
+------------------+
| lpad(5000,8,'*') |
+------------------+
| ****5000 |
+------------------+
select TRIM(' abc def ');
+-------------------+
| TRIM(' abc def ') |
+-------------------+
| abc def |
+-------------------+
--中间的空格也算做一位,[]
select substring('i love china' ,1,3);
+--------------------------------+
| substring('i love china' ,1,3) |
+--------------------------------+
| i l |
+--------------------------------+
3、日期
(1)CURDATE()和CURRENT_DATE() :获取当前日期函数;
select CURDATE(),CURRENT_DATE();
+------------+----------------+
| CURDATE() | CURRENT_DATE() |
+------------+----------------+
| 2022-08-07 | 2022-08-07 |
+------------+----------------+
(2)sysdate() : 返回系统当前日期和时间,语句开始执行的时间。
NOW():返回服务器的当前日期和时间;
CURTIME():返回当前时间,只包含时分秒;
select CURTIME(),NOW(),SYSDATE();
+-----------+---------------------+---------------------+
| CURTIME() | NOW() | SYSDATE() |
+-----------+---------------------+---------------------+
| 17:59:36 | 2022-08-07 17:59:36 | 2022-08-07 17:59:36 |
+-----------+---------------------+---------------------+
(3)UTC_DATE():返回世界标准时间日期函数;
UTC_TIME():返回世界标准时间函数;
(4)TIMEDIFF(expr1, expr2):返回两个日期相减相差的时间(时分秒)数;--必须传时间
select TIMEDIFF(SYSDATE(),'2022-04-11 11:06:07');
+-------------------------------------------+
| TIMEDIFF(SYSDATE(),'2022-04-11 11:06:07') |
+-------------------------------------------+
| 838:59:59 |
+-------------------------------------------+
(5)DATEDIFF(expr1, expr2):返回两个日期相减相差的天数;
select DATEDIFF(SYSDATE(),'2022-04-11');
+----------------------------------+
| DATEDIFF(SYSDATE(),'2022-04-11') |
+----------------------------------+
| 118 |
+----------------------------------+
(6)DATE_ADD(date,INTERVAL expr type):日期加上一个时间间隔值;
DATE_SUB(date,INTERVAL expr type):日期减去一个时间间隔值;
参数1是原始时间,参数expr代表具体的值,参数type代表是单位
select DATE_ADD(SYSDATE(),INTERVAL 1 DAY);
select DATE_ SUB (SYSDATE(),INTERVAL 1 DAY);
select DATE_ADD(SYSDATE(),INTERVAL 1 MONTH);
select DATE_ADD(SYSDATE(),INTERVAL 1 YEAR);
(7)DATE(date)、TIME(date)、YEAR(date):选取日期时间的各个部分:
SELECT TIME(SYSDATE()),DAY(SYSDATE()),DATE(SYSDATE()),MONTH(SYSDATE()),YEAR(SYSDATE());
(8)EXTRACT(unit FROM date):从日期中抽取出某个单独的部分或组合;
select EXTRACT(MONTH FROM NOW());
+---------------------------+
| EXTRACT(MONTH FROM NOW()) |
+---------------------------+
| 8 |
+---------------------------+
(9)DAYOFWEEK(date) 、DAYOFMONTH(date) 、DAYOFYEAR(date):返回日期在一周、一月、一年中是第几天
SELECT DAYOFWEEK(NOW()),DAYOFMONTH(NOW()),DAYOFYEAR(NOW());
(10)DAYNAME、MONTHNAME:返回日期的英文星期和月份名称;
SELECT DAYNAME(NOW()),MONTHNAME(NOW());
(11)DATE_FORMAT(date,format):格式化日期;
%Y-%m-%d %H:%i:%m Y: 4位年y:2位年 H:24小时 h:12小时
SELECT SYSDATE(),DATE_FORMAT(SYSDATE(),'%Y年%m月%d日');
+---------------------+---------------------------------------+
| SYSDATE() | DATE_FORMAT(SYSDATE(),'%Y年%m月%d日') |
+---------------------+---------------------------------------+
| 2022-08-07 18:06:59 | 2022年08月07日 |
+---------------------+---------------------------------------+
TIME_FORMATE(time,formate):格式化时间;
练习:
1. 求系统当前时间
2. 查询2020-1-18到现在的日期差
3. 查询3月以前的日期
4. 查询当前日期的年月日时分秒
5. 查询当前日期在一年,一月一周中是第几天
6.查询部门10,20的员工截止到2000年1月1日,工作了多少个月,入职的月份
7.如果员工试用期6个月,查询职位不是MANAGER的员工姓名,入职日期,转正日期,入职日期是第多少月,第多少周
select curdate(),current_date(),sysdate(),now();
+------------+----------------+---------------------+---------------------+
| curdate() | current_date() | sysdate() | now() |
+------------+----------------+---------------------+---------------------+
| 2022-08-07 | 2022-08-07 | 2022-08-07 20:35:05 | 2022-08-07 20:35:05 |
+------------+----------------+---------------------+---------------------+
select datediff(now(),'2020-1-8');
+----------------------------+
| datediff(now(),'2020-1-8') |
+----------------------------+
| 942 |
+----------------------------+
mysql> select date_sub(now(),interval 3 month);
+----------------------------------+
| date_sub(now(),interval 3 month) |
+----------------------------------+
| 2022-05-07 20:39:22 |
+----------------------------------+
select year(now()),month(now()),date(now()),hour(now()),minute(now()),SECOND(now());
+-------------+--------------+-------------+-------------+---------------+---------------+
| year(now()) | month(now()) | date(now()) | hour(now()) | minute(now()) | SECOND(now()) |
+-------------+--------------+-------------+-------------+---------------+---------------+
| 2022 | 8 | 2022-08-07 | 20 | 39 | 59 |
+-------------+--------------+-------------+-------------+---------------+---------------+
mysql> select dayofyear(now()),dayofmonth(now()),dayofweek(now());
+------------------+-------------------+------------------+
| dayofyear(now()) | dayofmonth(now()) | dayofweek(now()) |
+------------------+-------------------+------------------+
| 219 | 7 | 1 |
+------------------+-------------------+------------------+
select ename,month(hiredate) 入职月份,floor(datediff('2000-1-1',hiredate)/30) 入职几个月 from emp where deptno in(10,20) order by 入职几个月 desc;
+------------+----------+------------+
| ename | 入职月份 | 入职几个月 |
+------------+----------+------------+
| ADAMS | 5 | 153 |
| SCOTT | 4 | 154 |
| MILLER_1_2 | 1 | 218 |
| KING | 11 | 220 |
| FORD | 12 | 220 |
| CLARK | 6 | 226 |
| J_ONES | 4 | 228 |
| SMITH | 12 | 231 |
+------------+----------+------------+
select ename ,hiredate ,DATE_ADD(hiredate,INTERVAL 6 month) ,
-> FLOOR(DATEDIFF(SYSDATE(),HIREDATE)/30) 入职日期是第多少月,
-> Truncate((DATEDIFF(SYSDATE(),HIREDATE)/7),0) 第多少周
-> from emp where job!='manager';
+------------+------------+-------------------------------------+--------------------+----------+
| ename | hiredate | DATE_ADD(hiredate,INTERVAL 6 month) | 入职日期是第多少 月 | 第多少周 |
+------------+------------+-------------------------------------+--------------------+----------+
| 小白 | 2019-09-16 | 2020-03-16 | 35 | 150 |
| 小名 | 2022-07-31 | 2023-01-31 | 0 | 1 |
| SMITH | 1980-12-17 | 1981-06-17 | 506 | 2172 |
| aLLEN | 1981-02-20 | 1981-08-20 | 504 | 2163 |
| WARD | 1981-02-22 | 1981-08-22 | 504 | 2163 |
| MARTIN | 1981-09-28 | 1982-03-28 | 497 | 2131 |
| SCOTT | 1987-04-19 | 1987-10-19 | 429 | 1842 |
| KING | 1981-11-17 | 1982-05-17 | 495 | 2124 |
| TURNER | 1981-09-08 | 1982-03-08 | 498 | 2134 |
| ADAMS | 1987-05-23 | 1987-11-23 | 428 | 1837 |
| JAMES | 1981-12-03 | 1982-06-03 | 495 | 2122 |
| FORD | 1981-12-03 | 1982-06-03 | 495 | 2122 |
| MILLER_1_2 | 1982-01-23 | 1982-07-23 | 493 | 2115 |
+------------+------------+-------------------------------------+--------------------+----------+
(二)多行函数
1、count(*)符合条件的记录数
count(*)统计所有符合条件记录数
count(*) 和group by一起使用:统计每组记录数
count(列名):统计该列不为null的记录数
举例,数据库5条记录,有两条记录age为空
select count(age) from stu ;//3 查询stu表中age不为空的记录
select count(*) from stu ;//5
2、max(字段) 返回最大值
注意:select后面如果有聚合函数,不能和普通字段一起使用
获取年龄最大的学生信息
下面写法错误:聚合函数不能和普通字段一起使用。
id,name,sex不一定是最大年龄对应的值
select id,name,sex,max(age) from stu;
---子查询解决方案
select * from mystu where age=( select max(age) from mystu)--获取最大年龄
3、min(字段) 返回最大值
4、sum(字段) 返回总和
5、avg(字段) 取平均值
(三)流程控制函数
1.if(expr1,expr2,expr3):expr1如果为true,则返回expr2,如果为false,则返回expr3
select sal,if(sal>1500,'高薪','普通薪水') from emp;
2.ifnull(expr1,expr2)如果expr1不为空,则返回expr1,为空则返回expr2的值
3.
case value
when value then result
...
end
case之后给定的value值与每个when之后的value值进行比较,如果结果匹配,结果将返回then之后给出的result值
select ename,job,
case job
when 'CLERK' then '职员'
when 'MANAGER' then '经理'
else '销售人员'
end
from emp;
case
when [condition] then result
................
[else result]
end
第二种语法独立地测试每个条件,它们并不是已单个值为基础的,对于这两种用法而言,如果找不到匹配的值,则应将else子句包括进来并返回else子句所给定的结果,如果既没有匹配的值也没有给定else子句,则结果返回NULL值。
select ename,sal,
case
when sal<1000 then '低薪'
when sal<1500 then '普通薪水'
else '高薪'
end
from emp;
三、牛刀小试
1、创建表date_test,包含列d,类型为date型。试向date_test表中插入两条记录,一条当前系统日期记录,一条记录为“1998-08-18”。
create table date_test(
-> d date
-> );
insert into date_test values(sysdate());
insert into date_test values('1998-01-28');
alter table date_test modify column d timestamp;
insert into date_test values(); #如果是timstamp类型,输入null是系统时间
注:如果是timstamp类型,输入null是系统时间。
2、创建与dept表相同表结构的表dtest,将dept表中部门编号在40之前的信息插入该表。
创建与emp表结构相同的表empl,将其部门编号为前30号的员工信息复制到empl表。
通过子查询的方式创建一个表dept10,该表保存10号部门的员工数据。
create table dtest select * from dept where deptno<40;
create table empl select * from emp where deptno<30;
mysql> create table dept10 (select * from dept where deptno = 10);
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from dept10;
+--------+------------+----------+
| deptno | dname | loc |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
+--------+------------+----------+
1 row in set (0.00 sec)
3、简述五种约束的含义
非空:如果insert时,不传入值报错。
主键:字段值不能为空也不能重复。
外键:该字段的值必须是其他表中主键的值,如果其他表主键列没有值,该列不能存入。
唯一:输入的值不能重复。
检查:输入的值必须满足条件,不满足条件报错无法存入。
4、表复制时,复制结构和常规约束,不复制外键约束
5、创建商品表goods
商品编号整形主键自动增长 goods_id,
商品名称字符串非空默认‘’,goodes_name
分类编号, cat_id整数
品牌,brand_id整数
商品序列号,goods_sn字符串
商品数量,goods_number整数
商城价格,shop price 2位小数
市场价格,market_price 2位小数
点击次数 click_count整数
)
create table goods(
-> goods_id int primary key auto_increment,
-> goods_name varchar(10) not null default '',
-> cat_id int,
-> brand_id int,
-> goods_sn varchar(20),
-> goods_number int,
-> shop_price decimal(10,2),
-> market_price decimal(10,2),
-> click_count int
-> );
alter table goods drop brand_id;
alter table goods add column brand_id int;
alter table goods modify column brand_id varchar(10);
alter table goods change column brand_id brandid int;
6、练习1:
(1) 员工转正后,月薪上调500元,请查询出所有员工转正后的月薪。
(2)查询员工姓名,员工的工资,以及员工的年薪
(3)查询员工的年收入
(4)员工试用期6个月,转正后月薪上调20%,请查询出所有员工工作第一年的年薪所得(不考虑奖金部分,年薪的试用期6个月的月薪+转正后6个月的月薪)
(5)员工试用期6个月,转正后月薪上调20%,请查询出所有员工工作第一年的所有收入(需考虑奖金部分),要求显示列标题为员工姓名,工资收入,奖金收入,总收入。
#员工转正后,月薪上调500元,请查询出所有员工转正后的月薪
select ename,sal,sal+500 from emp;
#查询员工姓名,员工的工资,以及员工的年薪
select ename,sal,sal+500 from emp;
select ename,sal,(sal+ifnull(comm,0))*12 年薪 from emp;
#查询员工的年收入
select (sal + ifnull(comm,0))*12 年收入 from emp;
#员工试用期6个月,转正后月薪上调20%,请查询出所有员工工作第一年的年薪所得(不考虑奖金部分,年薪的试用期6个月的月薪+转正后6个月的月薪)
select (sal*6+sal*1.2*6) 第一年年薪 from emp;
#员工试用期6个月,转正后月薪上调20%,请查询出所有员工工作第一年的所有收入(需考虑奖金部分),要求显示列标题为员工姓名,工资收入,奖金收入,总收入
select ename 员工姓名,(sal*6+sal*1.2*6) 工资收入,(ifnull(comm,0)*12) 奖金 收入,(sal*6+sal*1.2*6+ ifnull(comm,0)*12) 总收入 from emp;