1.表的设计
CREATE TABLE `info_emp` (
`y_id` int(11) NOT NULL COMMENT '员工号',
`y_name` varchar(10) DEFAULT NULL COMMENT '员工姓名',
`y_sex` enum('男','女') DEFAULT NULL COMMENT '员工性别',
`y_age` int(11) DEFAULT NULL COMMENT '员工年龄',
`y_address` varchar(255) DEFAULT '不详' COMMENT '员工住址',
`b_id` int(11) DEFAULT NULL COMMENT '员工所在部门',
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`create_by` varchar(11) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(0) DEFAULT NULL COMMENT '修改人',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`remarks` varchar(255) DEFAULT NULL COMMENT '备注',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标记',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `y_id` (`y_id`) USING BTREE COMMENT '员工号应该是唯一的'
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8
CREATE TABLE `info_dept` (
`b_id` int(11) NOT NULL COMMENT '部门编号',
`b_name` varchar(255) NOT NULL COMMENT '部门名称',
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`create_by` varchar(11) NOT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(0) DEFAULT NULL COMMENT '修改人',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`remarks` varchar(255) DEFAULT NULL COMMENT '备注',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标记',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `b_id` (`b_id`) USING BTREE COMMENT '部门编号唯一'
) ENGINE=InnoDB AUTO_INCREMENT=1007 DEFAULT CHARSET=utf8
这里应该注意的是实际开发中,除了业务逻辑外应该必须要加入的字段,创建人,创建时间,修改人,修改时间,备注以及删除标记。以及一个与业务逻辑无关的id作为主键,规范手册中规定的是varchar类型,如果用int类型的话,主键递增的话,其他字段就不能递增了。
2.插入表中数据
create_time插入时,可以填写current_timestamp
3.查询
-- 更改表名
alter table bumen rename info_dept
-- 人事部年龄最大的女员工
select y_name,y_age,b_id from info_emp
where y_age = (
select max(y_age)
from info_emp
join info_dept
on info_emp.b_id = info_dept.b_id and b_name='人事部'
)
and y_sex='女'
-- 人事部年龄大于30岁的女同事,调到后勤部
update info_emp
set b_id=(
select b_id from info_dept where b_name='后勤部'
)-- 后勤部的id
where y_id in (
select * from (
select info_emp.y_id from info_emp
join info_dept
on info_dept.b_id=info_emp.b_id
where b_name='人事部' and y_age>30 and y_sex='女'
) xx
-- 人事部年龄大于30岁的女同事的员工id
)
-- 查询每个部门年龄最大的员工,显示部门名称和年龄和该员工的姓名
select b_name,y_age,y_name
from (select max(y_age) max_age,b_id
from info_emp
group by b_id) info_max_age
join info_emp
on info_max_age.max_age=info_emp.y_age
and info_emp.b_id=info_max_age.b_id
join info_dept
on info_emp.b_id=info_dept.b_id
-- 查询每个部门各有多少人,显示部门名字和人数,按人数倒序;如果人数相同,按部门编号倒序
select count(b_name),b_name,info_dept.b_id
from info_emp
join info_dept
on info_dept.b_id=info_emp.b_id
group by info_dept.b_id
order by count(b_name) desc,info_dept.b_id desc
-- 将张三的名字改为张三x 并调到软件部
update info_emp
set y_name='张三x',b_id=(
select b_id from info_dept
where b_name='开发部')
where y_name='张三'
select * from info_emp
-- 将后勤部大于60岁的员工删除
update info_emp
set del_flag='1'
where y_age>60
and b_id=(
select b_id from info_dept
where b_name='后勤部'
)
-- 查询人事部年龄不在45-50内的男性员工信息
select y_name,info_dept.b_name,y_age,y_sex
from info_emp
join info_dept
on info_emp.b_id=info_dept.b_id
where y_age not between 45 and 50
and y_sex='男' and b_name='人事部'
-- 人事部年龄大于30岁的女同事,调到后勤部 update info_emp set b_id=( select b_id from info_dept where b_name='后勤部' )-- 后勤部的id where y_id in ( select info_emp.y_id from info_emp join info_dept on info_dept.b_id=info_emp.b_id where b_name='人事部' and y_age>30 and y_sex='女' -- 人事部年龄大于30岁的女同事的员工id )
问题:
1093 - You can't specify target table 'info_emp' for update in FROM clause, Time: 0.000000s
错误的意思是说,不能先select出同一表中的某些值,再update这个表(在同一语句中),也就是说将select出的结果再通过中间表select一遍,这样就规避了错误。注意,这个问题只出现于mysql,mssql和oracle不会出现此问题。修改成以下写法就行,意思就是变个方向,在select外边套一层,让数据库认为你不是查同一表的数据作为同一表的更新数据:
update info_emp set b_id=( select b_id from info_dept where b_name='后勤部' )-- 后勤部的id where y_id in ( select * from ( select info_emp.y_id from info_emp join info_dept on info_dept.b_id=info_emp.b_id where b_name='人事部' and y_age>30 and y_sex='女' ) xx -- 人事部年龄大于30岁的女同事的员工id )