Mysql基本语法及其操作(三)

一、单表查询

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)或%:返回xy除的余数;

        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整数

        )

  • 删除brand_id字段
  • 添加brand_id字段
  • 修改brand_id, 类型为字符串
  • 修改brand_id的名字,新的名字是brandid
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;


你可能感兴趣的:(mysql,数据库,java)