查找当前薪水详情以及部门编号dept_no
这里我一开始是用的左外连接,要仔细看输出结果来决定用什么连接!
查找薪水记录超过15条的员工号emp_no以及其对应的记录次数t
有一个薪水表,salaries简况如下:
注意事项
- 由于是用到了聚合函数count,所以不能用where,应该用having
- 在一个查询中,HAVING 子句必须放在 GROUP BY 子句之后,必须放在 ORDER BY 子句之前
查找employees表emp_no与last_name的员工信息
推荐使用方法2,因为效率更高,其中逆序就是降序
- 查询奇数的一般方法:字段名 &(位运算) 1
- 查询偶数的一般方法:emp_no=(emp_no>>1<<1)
但是,以上的一般方法,针对的是字段全是数字的情况,如果对于身份证这种中间隐藏了一部分的,奇数无法使用,所以更好的方法是使用正则化表达式
正则化表达式
^aa:以aa开头
aa$:以aa结尾
.:匹配任何字符
[abc]:[字符集合],包含中括号内的字符
[^abc]或[!abc]:[字符集合],不包含中括号内的字符
a|b|c:匹配a或b或c,如(中|美)国
:匹配前面的子表达式0次或者多次。如,zo能匹配’z’以及’zoo’。*等价于{0,}
+:匹配前面的子表达式1次或者多次。如,’zo+’能匹配’zo’,但不能匹配’z’。+等价于{1,}
{n}:n是一个非负整数,匹配前面的子表达式2次。如,o{2} 能匹配’food’中的两个o,但不能匹配’Bob’中的o
{n, m}:m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。
对所有员工的薪水按照salary降序进行1-N的排名
窗口函数
获取所有员工当前的manager
这个答案感觉不太好理解
统计各个部门的工资记录数
这里选择用departments表(中间表)来连接其他两个表,我之前以为必须要和其他两个表有共同字段的表才可以作这个中间表,如果都是用的内连接(inner join)那无论用哪个表作中间表连接其他的表都可以
为什么dept_name 不属于聚合键,依然可以直接多表连接?
根据我查找的资料官方解释是:当group by 后面跟上主键或者不为空唯一索引时,查询是有效的,因为此时的每一笔数据都具有唯一性。
Mysql官方网站对此的描述链接:MySQL :: MySQL 5.7 Reference Manual :: 12.20.3 MySQL Handling of GROUP BY
dept_no是departments表的主键,所以以上代码的结果具有唯一性。也就是说depat_name是对应dept_no的。
获取所有非manager员工当前的薪水情况
思路:先找到所有非manager员工emp_no,再内连接工资表和部门表即可
使用join查询方式找出没有分类的电影id以及名称
两种答案
推荐第一种,第二种答案的子查询即使不内连接也是可以的,但是题目要求用join连接
将employees表的所有员工的last_name和first_name拼接起来作为Name
注意这里连接符号要用双引号引起来,不是单引号
创建一个actor表,包含如下列信息
批量插入数据
如果插入的字段和表的字段都是完全一样就可以用上面的写法,不一样就用下面的写法
批量插入数据,不使用replace操作
mysql中常用的三种插入数据的语句
insert into表示插入数据,数据库会检查主键,如果出现重复会报错;
replace into表示插入替换数据,需求表中有PrimaryKey或者unique索引,如果数据库已经存在数据,则用新数据替换,如果没有数据效果则和insert into一样;
insert ignore表示,如果中已经存在相同的记录,则忽略当前新数据;
创建一个actor_name表
MYSQL创建数据表的三种方法
常规创建
create table if not exists 目标表
复制表格
create 目标表 like 来源表
将table1的部分拿来创建table2
create table if not exists 要创建表的表名 (select 字段名 from 表名 where 条件)
对first_name创建唯一索引uniq_idx_firstname
MySQL中给字段创建四种不同类型索引的基本语法
针对actor表创建视图actor_name_view
注意上面的as不能丢
针对上面的salaries表emp_no字段创建索引idx_emp_no
注意这里创建表的时候已经创建了索引
在last_update后面新增加一列名字为create_date
构造一个触发器audit_log
上面的audit里的emp_no就是employees_test的id
在MySQL中,创建触发器语法如下
CREATE TRIGGER trigger_name
trigger_time trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
其中:
trigger_name:标识触发器名称,用户自行指定;
trigger_time:标识触发时机,取值为 BEFORE 或 AFTER;
trigger_event:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;
tbl_name:标识建立触发器的表名,即在哪张表上建立触发器;
trigger_stmt:触发器程序体,可以是一句SQL语句,或者用 BEGIN 和 END 包含的多条语句,每条语句结束要分号结尾。
【NEW 与 OLD 详解】
MySQL 中定义了 NEW 和 OLD,用来表示
触发器的所在表中,触发了触发器的那一行数据,具体地:
在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据;
在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;
使用方法: NEW.columnName (columnName 为相应数据表某一列名)
删除emp_no重复的记录,只保留最小的id对应的记录
这里把 select min(id) from titles_test group by emp_no得出的表重命名为titles_test2那就不是原表了,所以就可以删除了
注意:mysql不允许在子查询的同时删除原表数据,所以下面的写法是错误的!
将所有to_date为9999-01-01的全部更新为NULL
基本的数据更新语法
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005
本题考查的是replace函数,其中包含三个参数
- 第一个参数为该字段的名称
- 第二参数为该字段的需要被修改值
- 第三个参数为该字段修改后的值
如果不强制使用replace函数,那还有下面的方式
使用insert
使用replace into
将titles_test表名修改为titles_2017
alter table titles_test rename to titles_2017
1. 修改表名
alter table 表名 rename to 新的表名;
2. 修改表的字符集
alter table 表名 character set 字符集名称;
3. 添加一列
alter table 表名 add 列名 数据类型;
4. 修改列名称 类型
alter table 表名 change 列名 新列别 新数据类型;
alter table 表名 modify 列名 新数据类型;
5. 删除列
alter table 表名 drop 列名;
ALTER TABLE 表名 ADD 列名/索引/主键/外键等;
ALTER TABLE 表名 DROP 列名/索引/主键/外键等;
ALTER TABLE 表名 ALTER 仅用来改变某列的默认值;
ALTER TABLE 表名 RENAME 列名/索引名 TO 新的列名/新索引名;
ALTER TABLE 表名 RENAME TO/AS 新表名;
ALTER TABLE 表名 MODIFY 列的定义但不改变列名;
ALTER TABLE 表名 CHANGE 列名和定义都可以改变
在audit表上创建外键约束,其emp_no对应employees_test表的主键id
由于题目要求其emp_no对应employees_test表的主键id,所以才有下面的references employees_test(id)
创建外键语句结构
ALTER TABLE <表名>
ADD CONSTRAINT FOREIGN KEY (<列名>)
REFERENCES <关联表>(关联列)
查找字符串中逗号出现的次数
解析:把逗号去掉前后到长度差就是逗号到数目,LENGTH(replace(string, ',','')这个是去掉逗号的长度,不是把字符串中的逗号替换成空格
获取employees中的first_name
RIGHT函数它能返回从最右边开始指定长度的字符串。同理LEFT函数就是返回从最左边开始的指定长度字符串
按照dept_no进行汇总
聚合函数group_concat(X,Y),其中X是要连接的字段,Y是连接时用的符号,可省略,默认为逗号。此函数必须与GROUP BY配合使用。
此题以dept_no作为分组,将每个分组中不同的emp_no用逗号连接起来(即可省略Y)
平均工资
使用聚合函数,不用子查询,COUNT(1) 代表所有数据长度, -2 代表减去最大最小值的两个长
出现三次以上相同积分的情况
刷题通过的题目排名
找到每个人的任务
老是左右连接不知道用哪个,主要是没有彻底弄懂,A表左连接B表那么B表独有的字段可能会为null,A表右连接B表那么A表独有的字段可能会为null
牛客每个人最近的登录日期(二)
牛客每个人最近的登录日期(四)