mysql笔记

mysql笔记

一:sql语言分类

1.DDL:数据定义语言

create、alter、drop、rename、truncate

2.DML:数据操作语言

insert、delete、upate、select

3.DCL:数据控制语言

commit、rollback、savepoint、grant、revoke

二:基本规则

1.每条命令以;或者\g或者\G结束

2.命令过长可以分行写

3.关于标点符号

  • 必须英文输入
  • 字字符串和日期时间类型的数据一颗使用单引号(‘’)表示
  • 列的别名,尽量使用双引号(“”),而且尽量不要省略as

4.mysql在windows环境下大小写不敏感

在linux下敏感

5.统一书写规范

  • 数据库名、表名、表别名、字段名、等都小写
  • sql关键字、函数名、绑定变量都大写

6.注释

  • – 后面要跟一个空格
  • /* */

7.命令行导入数据库-------->命令行执行

source:绝对路径;	

三:基本语句

1.select * from table;

列的别名
SELECT id,name,age as age1 FROM USER;//as
SELECT id,name,age age1 FROM USER;//加空格
SELECT id,name,age "age1" FROM USER;//双引号,不要使用单引号
#结果中age属性更换名称叫age1
去除重复行(distinct)---->一般只能查一个的时候去重
SELECT DISTINCT age FROM user
空值参与运算----解决方案:用函数
  1. 空值:null
  2. null不等于0,‘’,‘null’
  3. 空值参与运算,结果一定为空,用函数IFNULL中用0来代替
着重号
当表名或者字段名与保留字重名时,加单引号,即着重号表示这不是保留字
查询常数
SELECT '公司名',name,age,FROM user;

常数的意思是在此处插入一列数据,全部为所写的数据

显示表结构
DESCRIBE TABLE;显示了表中字段的详细信息(或简写DESC table)
过滤数据
SELECT * FROM  WHERE id = 1; 

2.运算符

1.基本运算符
+ - / * div % mod---->只能代表基本运算,没有其他语言中的作用
SELECT 100 + 1 FROM DUAL;#101
SELECT 100 + '1' FROM DUAL;#101,会将字符转换成数值
SELECT 100 + 'a' FROM DUAL;#100,不可转换的字符看错0
SELECT 100 + NULL FROM DUAL;#100,null=0
SELECT 100 / 5 FROM DUAL;#20.0除法结果一定是浮点型
SELECT 100 / 5.0 FROM DUAL;#20.0
SELECT 100 / 3 FROM DUAL;#33.3333,结果为小数
SELECT 100 DIV 0 FROM DUAL;#分母为0,结果为NULL,但是数学中不成立
2.取模运算
SELECT 100 % 3,-12 % -5 FROM DUAL;#1,-2,符号与被除数一样
3.比较运算符

= <=>安全等于 <>(!=)不等于 < > >=

IS NULL IS NOTNULL LEAST最小值 GREATEST最大值 betwen and ISNULL IN NOT IN

LIKE REGEXP ESCAPE REGEXP

  • 字符串直接不存在隐式转换,比较是直接比较ASCII码 ‘a’=‘b’ —>0
  • 只要有null参与判断,结果为null 1=null---->null
  • slect name from user where sex=null;结果为空,不会有任何结果
  • <=>跟=的区别就是可以与null做运算;select 1<=>null,null=null from dual;结果为0 1
  • select 3<>2 ,‘4’<>null,‘’!=null from dual;#1 null null
  • select name from user where name like ‘%a%’;#模糊查询;‘a%’ a开头,‘%a’ a结尾,'_a%'第二个是a

ESCAPE
回避特殊符号的:使用转义符。例如:将[%]转为[ %]、[]转为[ ],然后再加上[ESCAPE‘$’]即可

SELECT job_id
FROM  jobs
WHERE job_id LIKE ‘IT\_%‘;

如果使用\表示转义,要省略ESCAPE。如果不是\,则要加上ESCAPE。

SELECT job_id
FROM  jobs
WHERE job_id LIKE ‘IT$_%‘ escape ‘$‘;

REGEXP运算符用来匹配字符串,语法格式为: expr REGEXP 匹配条件 。如果expr满足匹配条件,返回

(1)‘^’匹配以该字符后面的字符开头的字符串。
(2)‘$’匹配以该字符前面的字符结尾的字符串。
(3)‘.’匹配任何一个单字符。
(4)“[...]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”或“b”或“c”。为了命名字符的范围,使用一
个‘-’。“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。
(5)‘*’匹配零个或多个在它前面的字符。例如,“x*”匹配任何数量的‘x’字符,“[0-9]*”匹配任何数量的数字,
而“*”匹配任何数量的任何字符
mysql> SELECT 'shkstart' REGEXP '^s', 'shkstart' REGEXP 't$', 'shkstart' REGEXP 'hk';
| 'shkstart' REGEXP '^s' | 'shkstart' REGEXP 't$' | 'shkstart' REGEXP 'hk' |
|            1 |            1 |            1 |
1 row in set (0.01 sec)
mysql> SELECT 'atguigu' REGEXP 'gu.gu', 'atguigu' REGEXP '[ab]';
| 'atguigu' REGEXP 'gu.gu' | 'atguigu' REGEXP '[ab]' |
|             1 |            1 |
4.逻辑运算符
1.NOT 或者 !
2.AND 或者 &&
3.OR 或者 ||
4.XOR异或,当两边一真一假时,成立
5.位运算符

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.排序与分页

1.排序
order by—>默认升序

列的别名不可以在where中使用,只可以在order by中使用

  • ASC(ascend): 升序
  • DESC(descend):降序
  • ORDER BY 子句在SELECT语句的结尾。ASC(ascend): 升序
  • DESC(descend):降序
  • ORDER BY 子句在SELECT语句的结尾。
SELECT  last_name, job_id, department_id, hire_date
FROM   employees
ORDER BY hire_date DESC ;
SELECT employee_id,salary,department_id
FROM employee 
ORDER BY department_id DESC,salary ASC;
#可以使用不在SELECT列表中的列排序。
#在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第
#一列数据中所有值都是唯一的,将不再对第二列进行排序。
2.分页
LIMIT [位置偏移量,] 行数----->注意:LIMIT 子句必须放在整个SELECT语句的最后!
查询特定某页
--前10条记录:
SELECT * FROM 表名 LIMIT 0,10;
或者
SELECT * FROM 表名 LIMIT 10;
--第11至20条记录:
SELECT * FROM 表名 LIMIT 10,10;
#MySQL 8.0中可以使用“LIMIT 3 OFFSET 4”,意思是获取从第5条记录开始后面的3条记录,和“LIMIT
4,3;”返回的结果相同。
#公式:
SELECT * FROM table
LIMIT(PageNo - 1)*PageSize,PageSize;
查询具体某些条信息
#查询第32,33条信息
SELECT employee_id,salary,department_id
FROM employees
LIMIT  2 OFFSET 31
#查询工资最高的信息
SELECT employee_id,salary,department_id
FROM employees
ORDER BY salary DESC
LIMIT  1;
或者
SELECT employee_id,salary,department_id
FROM employees
LIMIT  31,2;#mysql8.0中2与31需要换位置,这是两者区别

4.多表查询

1.查询多个表

将不同表之间,用 id 相互联系,多表之间,需要有连接条件;如果查询语句中出现了多个表中都存在的字段,则必须指明此字段所在的表。

n个表,则至少有n-1个连接条件

#案例:查询员工的姓名及其部门名称
SELECT last_name, department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id;
2.多表查询的分类
1.等值连接 vs 非等值连接
  • 非等值连接

    select * from job 
    
    SELECT e.last_name,e.salary,j.grade_level
    FROM employees e,hob_grades j
    WHERE e.salary between j.lowest_sal and j.highest_sal;
    #WHERE e.salary >= jlowest_sal AND e.salary <= j.highest_sal
    
2.自连接 vs 非自连接
  • 练习:查询员工id,姓名及其管理者的id和姓名

  • 自连接指自己跟自己连接

    SELECT emp.employee_id, emp.last_name,mgr.employee_id,mgr.last_name
    FROM employees emp,employees mgr
    WHERE emp.magager_id = mgr.employee_id;
    
3.内连接 vs 外连接
  • 内连接: 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行

    SELECT last_name, department_name
    FROM employees, departments
    WHERE employees.department_id = departments.department_id;
    
  • 外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的
    行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)。

  • 如果是左外连接,则连接条件中左边的表也称为 主表 ,右边的表称为 从表 。

  • 如果是右外连接,则连接条件中右边的表也称为 主表 ,左边的表称为 从表 。

  • SQL92连接—>mysql不支持

    #左外连接
    SELECT last_name,department_name
    FROM employees ,departments
    WHERE employees.department_id = departments.department_id(+);
    #右外连接
    SELECT last_name,department_name
    FROM employees ,departments
    WHERE employees.department_id(+) = departments.department_id;
    

    而且在 SQL92 中,只有左外连接和右外连接,没有满(或全)外连接。

  • SQL99连接---->使用join…on------>mysql支持

    #内连接
    SELECT last_name,department_name,city
    FROM employees e 
    JOIN departments d
    ON e.departments_id=d.departments_id
    #JOIN ON 可以无限叠加
    
    #外连接
    SELECT lase_name,department_name
    FROM employee e 
    LEFT OUTER JOIN department d
    ON e.departments_id=d.departments_id
    #LEFT 改为RIGHT为右外连接 
    
    #满外连接---->mysql不支持
    SELECT lase_name,department_name
    FROM employee e 
    FULL OUTER JOIN department d
    ON e.departments_id=d.departments_id
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.UNION操作符

合并查询结果 利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并
时,两个表对应的列数和数据类型必须相同,并且相互对应。各个SELECT语句之间使用UNION或UNION
ALL关键字分隔。

  • SELECT column,... FROM table1
    UNION [ALL]
    SELECT column,... FROM table2
    
  • UNION 操作符返回两个查询的结果集的并集,去除重复记录

  • UNION ALL操作符返回两个查询的结果集的并集。对于两个结果集的重复部分,不去重

  • 注意:执行UNION ALL语句时所需要的资源比UNION语句少。如果明确知道合并数据后的结果数据
    不存在重复数据,或者不需要去除重复的数据,则尽量使用UNION ALL语句,以提高数据查询的效
    率。

  • #举例:查询部门编号>90或邮箱包含a的员工信息
    SELECT * FROM employees WHERE email LIKE '%a%' OR department_id>90;
    
    SELECT * FROM employees  WHERE email LIKE '%a%'
    UNION
    SELECT * FROM employees  WHERE department_id>90;
    #举例:查询中国用户中男性的信息以及美国用户中年男性的用户信息
    SELECT id,cname FROM t_chinamale WHERE csex='男'
    UNION ALLs
    SELECT id,tname FROM t_usmale WHERE tGender='male';
    
5.SQL99的外连接七种语法
  1. 中图:内连接

    #查询所有员工的部门,没有部门的不算
    SELECT employee_id,department_name
    FROM employees e JOIN department d
    ON e.department_id=d.department_id;
    
  2. 左上图:左外连接

    #查询所有员工的部门,没有部门的也算
    SELECT e.employee_id,d.department_name
    FROM employees e LEFT JOIN departments d
    ON e.department_id=d.department_id;
    
  3. 右上图:右外连接

    #查询所有部门所拥有的每一位员工信息,没有员工的部门也算一条记录
    SELECT e.employee_id,d.department_name
    FROM employees e RIGHT JOIN departments d
    ON e.department_id=d.department_id;
    
  4. 左中图

    #查询没有部门的员工
    SELECT e.employee_id,d.department_name
    FROM employees e LEFT JOIN departments d
    ON e.department_id=d.department_id
    WHERE d.department_id IS NULL
    
    
  5. 右中图

    #查询所有部门没有员工的部门
    SELECT e.employee_id,d.department_name
    FROM employees e RIGHT JOIN departments d
    ON e.department_id=d.department_id
    WHERE e.employee_id IS NULL
    
  6. 左下图:满外连接

    #方式一(左上 + UNION ALL + 右中)
    SELECT e.employee_id,d.department_name
    FROM employees e LEFT JOIN departments d
    ON e.department_id=d.department_id
    UNION ALL
    SELECT e.employee_id,d.department_name
    FROM employees e RIGHT JOIN departments d
    ON e.department_id=d.department_id
    WHERE e.employee_id IS NULL
    
    #方式二(左中图 + UNION ALL + 右上图)
    SELECT e.employee_id,d.department_name
    FROM employees e LEFT JOIN departments d
    ON e.department_id=d.department_id
    WHERE d.department_id IS NULL
    UNION ALL
    SELECT e.employee_id,d.department_name
    FROM employees e RIGHT JOIN departments d
    ON e.department_id=d.department_id;
    
  7. 右下图:

    #左中+右中
    SELECT e.employee_id,d.department_name
    FROM employees e LEFT JOIN departments d
    ON e.department_id=d.department_id
    WHERE d.department_id IS NULL
    UNION ALL
    SELECT e.employee_id,d.department_name
    FROM employees e RIGHT JOIN departments d
    ON e.department_id=d.department_id
    WHERE e.employee_id IS NULL
    
6.SQL99的新特性
1.自然连接NATURE JOIN

自然连接可以理解成SQL92中的等值连接,它会自动查询两张连接表中所有相同的字段,然后进行等值连接

SELECT employee_id,last_name,department_name
FROM emloyee e JOIN department d
ON e.department_id=d.department_id
ANDe.department_id=d.manger_id
#与下面一样的
SELECT employee_id,last_name,deoartment_name
FROM employee e NATURE JOIN department d;
2.USING

使用USING指定数据库表中同名字段进行等值连接,但是只能配合JOIN ON一起使用。不适用与自连接

SELECT employee_id,last_name,department_name
FROM employee e JOIN department d
ON e.department_id=d.department_id;
#使用using
SELECT employee_id,last_name,department_name
FROM employee e JOIN department d
USERING(department_id)
3.小总结

表连接约束条件可以右三种方式WHERE ON USING

  • WHERE: 适用于所有关联查询
  • ON:只能和JOIN一起使用,只能写关联条件,虽然关联条件可以和where一起写,但是分开可读性更好
  • USING只能和JOIN一起使用,而且要求两个关联字段在关联表中名称一致,而且只能表示关联字段值相等

5单行函数

1.数值函数

ABS(x) 返回x的绝对值
SIGN(X) 返回X的符号。正数返回1,负数返回-1,0返回0
PI() 返回圆周率的值
CEIL(x),CEILING(x) 返回大于或等于某个值的最小整数
FLOOR(x) 返回小于或等于某个值的最大整数
LEAST(e1,e2,e3…) 返回列表中的最小值
GREATEST(e1,e2,e3…****) 返回列表中的最大值
MOD(x,y) 返回X除以Y后的余数
RAND() 返回0~1的随机值
**RAND(x)**返回0~1的随机值,其中x的值用作种子值,相同的X值会产生相同的随机

ROUND(x) 返回一个对x的值进行四舍五入后,最接近于X的整数
ROUND(x,y) 返回一个对x的值进行四舍五入后最接近X的值,并保留到小数点后面Y位
TRUNCATE(x,y) 返回数字x截断为y位小数的结果
SQRT(x) 返回x的平方根。当X的值为负数时,返回NULL

RADIANS(x) 将角度转化为弧度,其中,参数x为角度值
DEGREES(x) 将弧度转化为角度,其中,参数x为弧度值

SELECT
ABS(-123),ABS(32),SIGN(-23),SIGN(43),PI(),CEIL(32.32),CEILING(-43.23),FLOOR(32.32),
FLOOR(-43.23),MOD(12,5)
FROM DUAL;

SELECT RAND(),RAND(),RAND(10),RAND(10),RAND(-1),RAND(-1)
FROM DUAL;

SELECT
ROUND(12.33),ROUND(12.343,2),ROUND(12.324,-1),TRUNCATE(12.66,1),TRUNCATE(12.66,-1)
FROM DUAL;

SELECT RADIANS(30),RADIANS(60),RADIANS(90),DEGREES(2*PI()),DEGREES(RADIANS(90))
FROM DUAL;
2.三角函数

SIN(x) 返回x的正弦值,其中,参数x为弧度值
ASIN(x) 返回x的反正弦值,即获取正弦为x的值。如果x的值不在-1到1之间,则返回NULL
COS(x) 返回x的余弦值,其中,参数x为弧度值
ACOS(x) 返回x的反余弦值,即获取余弦为x的值。如果x的值不在-1到1之间,则返回NULL
TAN(x) 返回x的正切值,其中,参数x为弧度值
ATAN(x) 返回x的反正切值,即返回正切值为x的值
ATAN2(m,n) 返回两个参数的反正切值
COT(x) 返回x的余切值,其中,X为弧度值

SELECT
SIN(RADIANS(30)),DEGREES(ASIN(1)),TAN(RADIANS(45)),DEGREES(ATAN(1)),DEGREES(ATAN2(1,1)
)
FROM DUAL;

**POW(x,y),**POWER(X,Y) 返回x的y次方
EXP(X) 返回e的X次方,其中e是一个常数,2.718281828459045
**LN(X),**LOG(X) 返回以e为底的X的对数,当X <= 0 时,返回的结果为NULL
LOG10(X) 返回以10为底的X的对数,当X <= 0 时,返回的结果为NULL
LOG2(X) 返回以2为底的X的对数,当X <= 0 时,返回NULL

SELECT POW(2,5),POWER(2,4),EXP(2),LN(10),LOG10(10),LOG2(4)
FROM DUAL;
3.进制转换

BIN(x) 返回x的二进制编码
HEX(x) 返回x的十六进制编码
OCT(x) 返回x的八进制编码
CONV(x,f1,f2) 返回f1进制数变成f2进制数

SELECT BIN(10),HEX(10),OCT(10),CONV(10,2,8)
FROM DUAL;
4.字符串函数

ASCII(S) 返回字符串S中的第一个字符的ASCII码值
CHAR_LENGTH(s) 返回字符串s的字符数。作用与CHARACTER_LENGTH(s)相同
LENGTH(s) 返回字符串s的字节数,和字符集有关
CONCAT(s1,s2,…,sn) 连接s1,s2,…,sn为一个字符串
**CONCAT_WS(x,s1,s2,…,sn)**同CONCAT(s1,s2,…)函数,但是每个字符串之间要加上x
**INSERT(str, idx, len,replacestr)**将字符串str从第idx位置开始,len个字符长的子串替换为字符串replacestr
REPLACE(str, a, b) 用字符串b替换字符串str中所有出现的字符串a
UPPER(s) 或 UCASE(s) 将字符串s的所有字母转成大写字母
LOWER(s) 或LCASE(s) 将字符串s的所有字母转成小写字母
LEFT(str,n) 返回字符串str最左边的n个字符
RIGHT(str,n) 返回字符串str最右边的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(s1 FROM s) 去掉字符串s开始与结尾的s1
**TRIM(LEADING s1FROM s)**去掉字符串s开始处的s1
**TRIM(TRAILING s1FROM s)**去掉字符串s结尾处的s1
REPEAT(str, n) 返回str重复n次的结果
SPACE(n) 返回n个空格
STRCMP(s1,s2) 比较字符串s1,s2的ASCII码值的大小
**SUBSTR(s,index,len)返回从字符串s的index位置其len个字符,作用与SUBSTRING(s,n,len)、*MID(s,n,len)***相同
**LOCATE(substr,str)返回字符串substr在字符串str中首次出现的位置,作用于POSITION(substrIN str)、INSTR(str,substr)**相同。未找到,返回0
ELT(m,s1,s2,…,sn)
返回指定位置的字符串,如果m=1,则返回s1,如果m=2,则返回s2,如
果m=n,则返回sn
FIELD(s,s1,s2,…,sn) 返回字符串s在字符串列表中第一次出现的位置

SELECT
ABS(-123),ABS(32),SIGN(-23),SIGN(43),PI(),CEIL(32.32),CEILING(-43.23),FLOOR(32.32),
FLOOR(-43.23),MOD(12,5)
FROM DUAL;

SELECT RAND(),RAND(),RAND(10),RAND(10),RAND(-1),RAND(-1)
FROM DUAL;

SELECT ROUND(12.33),ROUND(12.343,2),ROUND(12.324,-1),TRUNCATE(12.66,1),TRUNCATE(12.66,-1),SQRT(-5)
FROM DUAL;

SELECT RADIANS(30),RADIANS(60),RADIANS(90),DEGREES(2*PI()),DEGREES(RADIANS(90))
FROM DUAL;

SELECT
SIN(RADIANS(30)),DEGREES(ASIN(1)),TAN(RADIANS(45)),DEGREES(ATAN(1)),DEGREES(ATAN2(1,1))
FROM DUAL;

SELECT POW(2,5),POWER(2,4),EXP(2),LN(10),LOG10(10),LOG2(4)
FROM DUAL;

SELECT BIN(100),HEX(100),OCT(100),CONV(100,10,8)
FROM DUAL;

SELECT repeat('+helloword',3 ),LOCATE('o','helloword')
FROM DUAL;

SELECT FIELD('mm','hello','mm','amma'),FIND_IN_SET('mm','hello,mm,amma')
FROM DUAL;

SELECT REVERSE('HELLOWORD')
FROM DUAL;

SELECT NULLIF(1,2)
FROM DUAL;
5.日期函数
1. 获取日期、时间

**CURDATE() ,CURRENT_DATE()**返回当前日期,只包含年、月、日
**CURTIME() , CURRENT_TIME()**返回当前时间,只包含时、分、秒
NOW() / SYSDATE() / CURRENT_TIMESTAMP() / LOCALTIME() /
**LOCALTIMESTAMP()**返回当前系统日期和时间
**UTC_DATE()**返回UTC(世界标准时间)日期
**UTC_TIME()**返回UTC(世界标准时间)时间

2 日期与时间戳的转换

**UNIX_TIMESTAMP()**以UNIX时间戳的形式返回当前时间。SELECT UNIX_TIMESTAMP() ->1634348884
UNIX_TIMESTAMP(date) 将时间date以UNIX时间戳的形式返回。
FROM_UNIXTIME(timestamp) 将UNIX时间戳的时间转换为普通格式的时间

3. 获取月份、星期、星期数、天数等函数

YEAR(date) / MONTH(date) / DAY(date) 返回具体的日期值
**HOUR(time) / MINUTE(time) /SECOND(time)**返回具体的时间值
MONTHNAME(date) 返回月份:January,…
DAYNAME(date) 返回星期几:MONDAY,TUESDAY…SUNDAY
WEEKDAY(date) 返回周几,注意,周1是0,周2是1,。。。周日是6
QUARTER(date) 返回日期对应的季度,范围为1~4
WEEK(date) , WEEKOFYEAR(date) 返回一年中的第几周
DAYOFYEAR(date) 返回日期是一年中的第几天
DAYOFMONTH(date) 返回日期位于所在月份的第几天
**DAYOFWEEK(date)**返回周几,注意:周日是1,周一是2,。。。周六是7

EXTRACT(type FROM date) 返回指定日期中特定的部分,type指定返回的值

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SELECT EXTRACT(MINUTE FROM NOW()),EXTRACT( WEEK FROM NOW()),
EXTRACT( QUARTER FROM NOW()),EXTRACT( MINUTE_SECOND FROM NOW())
FROM DUAL;
5 时间和秒钟转换的函数

**TIME_TO_SEC(time)**将 time 转化为秒并返回结果值。转化的公式为: 小时3600+分钟60+秒
SEC_TO_TIME(seconds) 将 seconds 描述转化为包含小时、分钟和秒的时间

6 计算日期和时间的函数

**DATE_ADD(datetime, INTERVAL expr type),ADDDATE(date,INTERVAL expr type)**返回与给定日期时间相差INTERVAL时间段的日期时间
**DATE_SUB(date,INTERVAL expr type),SUBDATE(date,INTERVAL expr type)**返回与date相差INTERVAL时间间隔的日期

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ADDDATE('2021-10-21 23:32:12',INTERVAL 1 SECOND) AS col3,
DATE_ADD('2021-10-21 23:32:12',INTERVAL '1_1' MINUTE_SECOND) AS col4,
DATE_ADD(NOW(), INTERVAL -1 YEAR) AS col5, #可以是负数
DATE_ADD(NOW(), INTERVAL '1_1' YEAR_MONTH) AS col6 #需要单引号
FROM DUAL;
SELECT DATE_SUB('2021-01-21',INTERVAL 31 DAY) AS col1,
SUBDATE('2021-01-21',INTERVAL 31 DAY) AS col2,
DATE_SUB('2021-01-21 02:01:01',INTERVAL '1 1' DAY_HOUR) AS col3
FROM DUAL;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SELECT
ADDTIME(NOW(),20),SUBTIME(NOW(),30),SUBTIME(NOW(),'1:1:3'),DATEDIFF(NOW(),'2021-10-
01'),
TIMEDIFF(NOW(),'2021-10-25 22:10:10'),FROM_DAYS(366),TO_DAYS('0000-12-25'),
LAST_DAY(NOW()),MAKEDATE(YEAR(NOW()),12),MAKETIME(10,21,23),PERIOD_ADD(20200101010101,
10)
FROM DUAL;
7 日期的格式化与解析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SELECT DATE_FORMAT(NOW(), '%H:%i:%s');
| DATE_FORMAT(NOW(), '%H:%i:%s') |
| 22:57:34 
6流程控制函数
IF(value,value1mvable2)–>value是true,返回value1,否则返回value2
 SELECT last_name,salary,IF(salary>=6000,'heigh','low')
 FROM employees;

IFNULL(value,value1)–>value是null,返回value,否则返回value1

SELECT last_name,salary,IFNULL(department_id,'老板'),IF(salary>=6000,'heigh','low')
FROM employees;

**CASE WHEN…THEN…WHEN…**类似于if else

SELECT last_name,salary,CASE WHEN salary>=15000 THEN '1' 
WHEN  salary>=10000 THEN'2'
WHEN salary>=8000 THEN '3'
ELSE '4' END "detail"
FROM employees;

CASE expr WHEN …THEN… WHEN … THEN … [ELSE 值n] END–>类似于switch case

SELECT employee_id,last_name,department_id,salary,CASE department_id
    WHEN 10 THEN salary*1.1
	WHEN 20 THEN salary*1.2
	WHEN 30 THEN salary*1.3
	ELSE salary*1.4 END "detail"
FROM employees;

 SELECT employee_id,last_name,department_id,salary,CASE department_id
  WHEN 10 THEN salary*1.1
	WHEN 20 THEN salary*1.2
	WHEN 30 THEN salary*1.3
	END "detail"
FROM employees
WHERE department_id IN (10,20,30);
7. 加密与解密函数

加密与解密函数主要用于对数据库中的数据进行加密和解密处理,以防止数据被他人窃取。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

SELECT md5('123')
->202cb962ac59075b964b07152d234b70

mysql> SELECT DECODE(ENCODE('mysql','mysql'),'mysql');
+-----------------------------------------+
| DECODE(ENCODE('mysql','mysql'),'mysql') |
+-----------------------------------------+
| mysql                  |
+-----------------------------------------+
1 row in set, 2 warnings (0.00 sec)
8. MySQL信息函数

MySQL中内置了一些可以查询MySQL信息的函数,这些函数主要用于帮助数据库开发或运维人员更好地
对数据库进行维护工作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| test    |
+------------+

mysql> SELECT USER(), CURRENT_USER(), SYSTEM_USER(),SESSION_USER();
+----------------+----------------+----------------+----------------+
| USER()     | CURRENT_USER() | SYSTEM_USER() | SESSION_USER() |
+----------------+----------------+----------------+----------------+
| root@localhost | root@localhost | root@localhost | root@localhost |
+----------------+----------------+----------------+----------------+
9.其他函数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

# 如果n的值小于或者等于0,则只保留整数部分
mysql> SELECT FORMAT(123.123, 2), FORMAT(123.523, 0), FORMAT(123.123, -2);
+--------------------+--------------------+---------------------+
| FORMAT(123.123, 2) | FORMAT(123.523, 0) | FORMAT(123.123, -2) |
+--------------------+--------------------+---------------------+
| 123.12       | 124        | 123         |
+--------------------+--------------------+---------------------+
1 row in set (0.00 sec)

mysql> SELECT INET_ATON('192.168.1.100');
+----------------------------+
| INET_ATON('192.168.1.100') |
+----------------------------+
|         3232235876 |
+----------------------------+
1 row in set (0.00 sec)

mysql> SELECT CHARSET('mysql'), CHARSET(CONVERT('mysql' USING 'utf8'));
+------------------+----------------------------------------+
| CHARSET('mysql') | CHARSET(CONVERT('mysql' USING 'utf8')) |
+------------------+----------------------------------------+
| utf8mb4     | utf8                  |
+------------------+----------------------------------------+
1 row in set, 1 warning (0.00 sec)

6.聚合函数

聚合(或聚集、分组)函数,它是对一组数据进行汇总的函数,输入的是一组数据的集合,输出的是单个值。

聚合函数作用于一组数据,并对一组数据返回一个值。

1.常用聚合函数
  • AVG()—>只适用于数值类型的字段(AVG = SUM / COUNT)

  • SUM()–>只适用于数值类型的字段

  • MAX()---->字符类型是排序

  • MIN()---->字符类型是排序

  • COUNT()------>效率count(*)最高

    SELECT AVG(salary), MAX(salary),MIN(salary), SUM(salary)
    FROM  employees
    
    SELECT MIN(hire_date), MAX(hire_date)
    FROM employees;
    
    SELECT COUNT(*)
    FROM employees
    WHERE department_id = 50;
    
2.group by的使用:根据此字句中的条件将表中数据分为若干组
#每个部门的平均工资,根据department_id分组
SELECT department_id,AVG(salary)
from employees
GROUP BY department_id;

#每个部门的平均工资,根据department_id和job_id分组
SELECT department_id,job_id,AVG(salary)
from employees
GROUP BY department_id,job_id;#此处两者前后顺序不影响结果

#下面是错误的
SELECT department_id,job_id,AVG(salary)
from employees
GROUP BY department_id;#没有根据job_id分组,则不可明确的显示是哪个job_id,可以运行,但是错误

结论:

1.ELECT 中出现的非组函数字段必须声明在group by 中,

反之,group by 声明的字段可以不出现在SELECT中。

2.group by 声明在from后,shere后,order by 前,limit前

3.mysql中group by 可以使用 with rollup,但是此时,慎重使用order by(互斥)

#使用 WITH ROLLUP 关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算#查询出的所有记录的总和,即统计记录数量。
SELECT department_id,AVG(salary)
FROM employees
WHERE department_id > 80
GROUP BY department_id WITH ROLLUP;
3.having的使用----->用来过滤数据的

开发中,使用having的前提是使用了group by(不用无意义)

having的意义就是替换在出现group by中的wh ere

练习:查询各个部门最高工资比1W高的部门

错误写法:当where中出现聚合函数时,需要使用having
SELECT department_id,MAX(salary)
FROM employees
WHERE MAX(salary)>10000
GROUP BY department_id;

#正确写法:having需要写在group by后
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000;

#另一种正确写法:但是效率相较于having,低很多
SELECT department_id,MAX(salary)
FROM employees
WHERE salary>10000
GROUP BY department_id;

练习:查询id为10,20,30,40,50,60中部门最高工资比10000高的部门信息

方式一的执行效率高于方式二

#方式一

SELECT department_id,MAX(salary)
FROM employees
WHERE department_id IN (10,20,30,40,50,60) 
GROUP BY department_id
HAVING MAX(salary)>10000;

#方式二
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id
HAVING department_id IN (10,20,30,40,50,60) AND MAX(salary)>10000;

结论:

当过滤条件中右聚合函数时,则此过滤条件必须声明在HAVING中

当过滤条件中没有聚合函数时,则此过滤条件声明在HAVING和WHERE中都可以,但是建议声明在WHERE中

WHERE 和 HAVING的对比

  1. WHERE可以直接使用表中的字段为筛选条件,但是不可以使用分组中的计算函数作为筛选条件;having必须与group by 配合使用,可以把分组计算的函数和分组字段作为筛选条件
  2. 如果需要通过连接从关联表中获取需要的数据,where是先筛选后连接,而having是先连接后筛选
  3. 适用范围来说,having使用范围更广
  4. 如果没有过滤函数中,where中执行的效率比having更高
4.SQL底层执行原理
  1. sql语句的完整结构

    #SQL92
    SELECT ...,...,..
    FROM ...,..,..,
    WHERE 多表连接条件 AND 不包含聚合函数的过滤条件
    GROUP BY ......
    HAVING 包含聚合函数的过滤条件
    ORDER BY ...,..,(ASC,DESC)
    LIMIT ......
    
    #sql99
    SELECT ...,...,..(存在聚合函数)
    FROM ...(LEFT,RIGHT)JOIN ... ON  多表连接条件
    (LEFT,RIGHT)JOIN ... ON...
    WHERE 不包含聚合函数的过滤条件
    GROUP BY ......
    HAVING 包含聚合函数的过滤条件
    ORDER BY ...,..,(ASC,DESC) 
    LIMIT ......
    
  2. SQL语句的执行过程

FROM----->ON----->(LEFT/RIGHT JOIN)----->WHERE------>GROUP BY ------> HAVING ----->SELECT---->DISTINCT------>ORDER BY ----->LIMIT

7.子查询:

子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL 4.1开始引入

SQL 中子查询的使用大大增强了 SELECT 查询的能力,因为很多时候查询需要从结果集中获取数据,或者需要从同一个表中先计算得出一个数据结果,然后与这个数据结果(可能是某个标量,也可能是某个集合)进行比较

1.子查询基本使用
SELECT  select_list
FROM table
WHERE expr opterator(
	SELECT  select_list
    FROM table
    WHERE expr
);

练习:谁的工资比Abel高

SELECT last_name,salary
FROM employees
WHERE salary > (
	SELECT salary
	FROM employees
	WHERE last_name = 'Abel'
	);
  • 子查询(内查询)在主查询之前一次执行完成。

  • 子查询的结果被主查询(外查询)使用 。

  • 注意事项:

    1. 子查询要包含在括号内
    2. 将子查询放在比较条件的右侧
    3. 单行操作符对应单行子查询,多行操作符对应多行子查询
2. 子查询的分类

分类方式1:
我们按内查询的结果返回一条还是多条记录,将子查询分为 单行子查询 、 多行子查询

分类方式2:

我们按内查询是否被执行多次,将子查询划分为 相关(或关联)子查询不相关(或非关联)子查询

子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件进行执行,那么这样的子查询叫做不相关子查询。

同样,如果子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部,这种嵌套的执行方式就称为相关子查询

比如:

​ 相关子查询:查询工资大于本部门平均工资的员工信息

​ 不相关子查询:查询工资大于本公司平均工资的员工信息

3.子查询具体方式

编写技巧:

1.从外往里写:

2.从里往外写:

练习:查询工资比149号员工工资高的员工信息

SELECT salary
FROM employees
WHERE salary>(
	SELECT salary
	FROM employees
	WHERE employee_id=149
);

练习:返回公司工资最少的员工的last_name,job_id和salary

SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
	SELECT MIN(salary)
	FROM employees
);

题目:查询与141号或174号员工的manager_id和department_id相同的其他员工的employee_id,
manager_id,department_id

#方式一:
SELECT employee_id,manager_id,department_id
FROM employees
WHERE manager_id IN (
		SELECT manager_id
		FROM employees
		WHERE employee_id IN (141,174)
) AND department_id in (
		SELECT department_id
		FROM employees
		WHERE employee_id IN (141,174)
) AND employee_id not in (141,174);
#方式二
SELECT employee_id, manager_id, department_id
FROM employees
WHERE (manager_id, department_id) IN
          (SELECT manager_id, department_id
           FROM  employees
           WHERE employee_id IN (141,174))
AND employee_id NOT IN (141,174);

题目:查询最低工资大于50号部门最低工资的部门id和其最低工资

SELECT department_id,salary
FROM employees
WHERE department_id is not null
GROUP BY department_id
HAVING MIN(salary)>(
			SELECT MIN(salary)
			FROM employees
			WHERE department_id=50
)

子查询中的CASE问题

题目:显示员工的employee_id和last_name,和location,齐总若员工的department_id与location-id为1800的department_id相同,则location 为Canada,否则为USA

SELECT employee_id,last_name,(CASE department_id 
								WHEN (  SELECT department_id
                                        FROM departments
                                        where location_id = 1800)
								THEN 'Canada'
								ELSE 'USA' end) location
from employees e

子查询中的空值问题

子查询不返回任何行

SELECT last_name, job_id
FROM  employees
WHERE job_id =
       (SELECT job_id
        FROM  employees
        WHERE last_name = 'Haas');

非法使用子查询(比如返回值不不止一个,不可以用等于号)

SELECT employee_id, last_name
FROM  employees
WHERE salary =
       (SELECT  MIN(salary)
        FROM   employees
        GROUP BY department_id);
4.多行子查询
1.返回结果是多行
  • IN 等于列表中的任意一个

    # 查询薪水最低的人的id和名字
    SELECT employee_id,last_name
    FROM employees
    WHERE salary IN (
    							SELECT MIN(salary)
    							FROM employees
    							GROUP BY department_id
    );
    
  • ANY 需要和单行比较操作符一起使用,和子查询返回的某一个值比较

    #练习:返回其它job_id中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
    #方法一:老方法
    SELECT employee_id,last_name,job_id,salary
    FROM employees
    WHERE salary<(
    			SELECT MAX(salary)
    			FROM employees
    			WHERE job_id='IT_PROG'
    ) AND job_id!='IT_PROG';
    
    #方式二:用ANY
    SELECT employee_id,last_name,job_id,salary
    FROM employees
    WHERE salary< ANY (
    			SELECT salary
    			FROM employees
    			WHERE job_id='IT_PROG'
    ) AND job_id!='IT_PROG';
    
  • ALL 需要和单行比较操作符一起使用,和子查询返回的所有值比较

    #返回其它job_id中比job_id为‘IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id以及salary
    #方式一:老方法
    SELECT employee_id,last_name,job_id,salary
    FROM employees
    WHERE salary<(
    			SELECT MIN(salary)
    			FROM employees
    			WHERE job_id='IT_PROG'
    ) AND job_id!='IT_PROG';
    
    #方式二:ALL
    FROM employees
    WHERE salary< ALL (
    			SELECT salary
    			FROM employees
    			WHERE job_id='IT_PROG'
    ) AND job_id!='IT_PROG';
    
  • SOME 实际上是ANY的别名,作用相同,一般常使用ANY

2.嵌套查询(较难)
#查询平均工资最低的部门id
#方式1:
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) = (
            SELECT MIN(avg_sal)
            FROM (
                    SELECT AVG(salary) avg_sal
                    FROM employees
                    GROUP BY department_id
            ) dept_avg_sal   #把结果当做一个新表来查询
)

#方式2:
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) <= ALL (
                SELECT AVG(salary) avg_sal
                FROM employees
                GROUP BY department_id
)

3.空值问题
#错误写法
SELECT last_name
FROM employees
WHERE employee_id NOT IN (
            SELECT manager_id
            FROM employees
);

#正确写法
SELECT last_name
FROM employees
WHERE employee_id NOT IN (
						SELECT manager_id
						FROM employees
    					WHERE manager_id is not null
)
		
4.相关子查询

如果子查询的执行依赖于外部查询,通常情况下都是因为子查询中的表用到了外部的表,并进行了条件关联,因此每执行一次外部查询,子查询都要重新计算一次,这样的子查询就称之为 关联子查询 。

#题目:查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id
#方式一:相关子查询
SELECT last_name,salary,department_id
from employees e1
where salary > (
						SELECT AVG(salary)
						from employees e2
						where department_id = e1.department_id
);
#方式二:在 FROM 中使用子查询
SELECT e1.last_name,e1.salary,e1.department_id
from employees e1,(
							select department_id,avg(salary) as avg_sal
							from employees 
							GROUP BY department_id
)  as e2
where e1.department_id = e2.department_id
and e1.salary > e2.avg_sal
#查询员工的id,salary,按照department_name排序
select employee_id,salary
from employees e
order by (
					select department_name
					from departments d
					where e.department_id= d.department_id
)
#若employees表中employee_id与job_history表中employee_id相同的数目不小于2,输出这些相同id的员工的employee_id,last_name和其job_id
select employee_id,last_name,job_id
from employees e
where 2<=(
					select count(*)
					from job_history j
					where e.employee_id=j.employee_id
);

5.EXISTS与NOT EXISTS关键字

关联子查询通常与EXISTS操作符一起是使用,用来检查查询中是否存在满足条件的行

如果在子查询中没有满足条件的行

  • 返回FALSE
  • 继续在子查询中查询

如果如果在子查询中有满足条件的行

  • 不在子查询中继续查找
  • 条件返回TRUE

NOT EXISTS关键字表示不存在某种条件,则返回TRUE,否则返回FALSE

exists练习

#查询公司管理者的employee_id,last_name,job_id,department_id信息
#自连接
select distinct mgr.employee_id,mgr.last_name,mgr.job_id,mgr.department_id
from employees  e join  employees mgr
on e.manager_id=mgr.employee_id
#子查询
SELECT  employee_id,last_name,job_id,department_id
from employees
where employee_id in (
			select distinct manager_id
			from employees
);
#使用exists
SELECT  employee_id,last_name,job_id,department_id
from employees e1
where EXISTS(
					SELECT *
					from employees e2
					where e1.employee_id= e2.manager_id
);

not exists练习

#查询departments表中,不存在于employees表中的部门的department_id和department_name
#not exists
select department_id,department_name 
from  departments d
where not EXISTS(
							select *
							from employees e
							where e.department_id = d.department_id
);
#右外连接
select  d.department_id,d.department_name 
from employees e RIGHT join departments d  on
 e.department_id=d.department_id
 where e.department_id is null
#子查询练习题
#1.查询和Zlotkey相同部门的员工姓名和工资
select e1.last_name,e1.salary
from employees e1
where  department_id = ( 
			select department_id
			from employees e2
			where e2.last_name='Zlotkey'
);

#2.查询工资比公司平均工资高的员工的员工号,姓名和工资。
select employee_id,last_name,salary
from employees
where salary >= (
				select avg(salary)
				FROM employees
);


#3.选择工资大于所有JOB_ID = 'SA_MAN'的员工的工资的员工的last_name, job_id, salary

select last_name,job_id,salary
from employees
where salary >= ALL(
						select salary
						from employees
						where job_id='SA_MAN'

);


#4.查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名
select employee_id,last_name
from employees
WHERE job_id in (
						select job_id
						from employees
						where last_name like '%u%'
);




#5.查询在部门的location_id为1700的部门工作的员工的员工号

select employee_id,last_name
from employees e,departments d
where e.department_id=d.department_id
and d.location_id=1700

#6.查询管理者是King的员工姓名和工资
select last_name,salary
from employees
where manager_id = (
							select manager_id
							from employees
							where last_name='King'
							and manager_id is not null
) and last_name <>'King';



#7.查询工资最低的员工信息: last_name, salary
SELECT last_name,salary
from employees
where salary <= All(
							SELECT salary
							from employees
	);


#8.查询平均工资最低的部门信息
select  department_id
from employees
GROUP BY department_id
having avg(salary) <= (
													select min(avg_sal) 
													from (select avg(salary) as avg_sal
													from employees
													GROUP BY department_id) as _t)
			


#9.查询平均工资最低的部门信息和该部门的平均工资(相关子查询)

select department_id,avg(salary)
from employees
GROUP BY department_id
having avg(salary) <= (
													select min(avg_sal) 
													from (select avg(salary) as avg_sal
													from employees
													GROUP BY department_id) as _t)



#10.查询平均工资最高的 job 信息

select department_id,avg(salary),job_id
from employees
GROUP BY job_id
having avg(salary) >=  (
													select MAX(avg_sal) 
													from (
																select avg(salary) as avg_sal
																from employees
																GROUP BY job_id
													) as _t
	)
													

#11.查询平均工资高于公司平均工资的部门有哪些?

select department_id,avg(salary)
from employees
GROUP BY department_id
having avg(salary) >= (
												select avg(salary)
												from employees
													
)


#12.查询出公司中所有 manager 的详细信息

select DISTINCT manager_id
from employees
where manager_id is not null


#13.各个部门中 最高工资中最低的那个部门的 最低工资是多少?

select Max(salary) as max,min(salary) as min 
from employees
GROUP BY department_id


#14.查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary
----------------------------------------
SELECT last_name, department_id, email, salary
from employees
where manager_id = 


select manager_id,AVG(salary)
from employees
GROUP BY department_id
having avg(salary) >= all(
								select avg(salary)
								from employees
								GROUP BY department_id
) and manager_id<>90 ;


#15. 查询部门的部门号,其中不包括job_id是"ST_CLERK"的部门号

select distinct department_id
FROM employees
WHERE job_id <>'ST_CLERK' and department_id is not null

#16. 选择所有没有管理者的员工的last_name

SELECT last_name
from employees
where manager_id is null

#17.查询员工号、姓名、雇用时间、工资,其中员工的管理者为 'De Haan'
select employee_id,last_name,hire_date,salary
from employees
where manager_id = (
										select manager_id
										from employees
										where last_name='De Haan'
);



#18.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资(相关子查询)


SELECT employee_id,department_id,last_name,salary
from employees e
GROUP BY department_id
having  e.salary > all(
								SELECT  avg(salary)
								from employees d
								GROUP BY department_id
								having e.department_id=d.department_id
);



#19.查询每个部门下的部门人数大于 5 的部门名称(相关子查询)

SELECT department_name
from departments d
GROUP BY department_id
having 5 < (
						select count(*)
						from employees e
						GROUP BY department_id
						having e.department_id=d.department_id
);



#20.查询每个国家下的部门个数大于 2 的国家编号(相关子查询)

select country_id
from countries
where 2 < region_id


s not null

#13.各个部门中 最高工资中最低的那个部门的 最低工资是多少?

select Max(salary) as max,min(salary) as min
from employees
GROUP BY department_id

#14.查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary

SELECT last_name, department_id, email, salary
from employees
where manager_id =

select manager_id,AVG(salary)
from employees
GROUP BY department_id
having avg(salary) >= all(
select avg(salary)
from employees
GROUP BY department_id
) and manager_id<>90 ;

#15. 查询部门的部门号,其中不包括job_id是"ST_CLERK"的部门号

select distinct department_id
FROM employees
WHERE job_id <>‘ST_CLERK’ and department_id is not null

#16. 选择所有没有管理者的员工的last_name

SELECT last_name
from employees
where manager_id is null

#17.查询员工号、姓名、雇用时间、工资,其中员工的管理者为 ‘De Haan’
select employee_id,last_name,hire_date,salary
from employees
where manager_id = (
select manager_id
from employees
where last_name=‘De Haan’
);

#18.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资(相关子查询)

SELECT employee_id,department_id,last_name,salary
from employees e
GROUP BY department_id
having e.salary > all(
SELECT avg(salary)
from employees d
GROUP BY department_id
having e.department_id=d.department_id
);

#19.查询每个部门下的部门人数大于 5 的部门名称(相关子查询)

SELECT department_name
from departments d
GROUP BY department_id
having 5 < (
select count(*)
from employees e
GROUP BY department_id
having e.department_id=d.department_id
);

#20.查询每个国家下的部门个数大于 2 的国家编号(相关子查询)

select country_id
from countries
where 2 < region_id

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值