您的位置:首页 > 其它

一个馒头引发的血案 --- 需要嵌套查询而不用嵌套查询的后果

2017-10-10 20:53 295 查看
-- 部门表

create table dept

(
dept_id int,
dept_name nvarchar(16),
dept_address nvarchar(16),
primary key (dept_id)

) engine = 'InnoDB' charset utf8;

insert into dept values(1, '物理系', '剑桥');

insert into dept values(2, '数学系', '巴黎');

insert into dept values(3, '哲学系', '汉堡');

-----------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------

-- 员工表

create table emp

(
emp_id int,
emp_name nvarchar(16),
emp_sex nchar(1),
emp_age int,
emp_job nvarchar(8),
emp_leader nvarchar(8),
emp_hiredate date,
emp_salary int,
emp_bonus int,
dept_id int,
primary key (emp_id),
foreign key (dept_id) references dept(dept_id)

) engine = 'InnoDB' charset utf8;

insert into emp values (20170001, '牛顿', '男', 27, '物理学家', '上帝', '1666-06-23', 8000, 4000, 1);

insert into emp values (20170002, '爱因斯坦', '男', 22, '物理学家', '牛顿', '1905-06-23', 9999, 8000, 1);

insert into emp values (20170003, '波尔', '男', 50, '物理学家', '上帝', '1880-09-23', 6000, 4000, 1);

insert into emp values (20170004, '薛定谔', '男', 45, '物理学家', '上帝', '1890-09-30', 7000, 3000, 1);

insert into emp values (20170005, '海森堡', '男', 22, '物理学家', '波尔', '1920-02-26', 5000, 2000, 1);

insert into emp values (20170006, '洛伦兹', '男', 70, '物理学家', '上帝', '1860-01-14', 8000, 6000, 1);

insert into emp values (20170007, '居里夫人', '女', 42, '物理学家', '上帝', '1890-03-12', 8000, 8000, 1);

insert into emp values (20170008, '拉格朗日', '男', 40, '数学家', '欧拉', '1689-07-20', 6000, 4000, 2);

insert into emp values (20170009, '欧拉', '男', 60, '数学家', '上帝', '1726-05-24', 8000, 6000, 2);

insert into emp values (20170010, '罗尔', '男', 40, '数学家', '欧拉', '1865-06-13', 4000, 4000, 2);

insert into emp values (20170011, '洛必达', '男', 40, '数学家', '泰勒', '1920-05-14', 4000, 2000, 2);

insert into emp values (20170012, '泰勒', '男', 40, '数学家', '欧拉', '1789-07-24', 8000, 8000, 2);

insert into emp values (20170013, '达朗贝尔', '男', 40, '数学家', '欧拉', '1889-07-20', 6000, 4000, 2);

insert into emp values (20170014, '阿尔贝', '男', 22, '数学家', '达朗贝尔', '1920-07-20', 4000, 3000, 2);

insert into emp values (20170015, '康德', '男', 65, '哲学家', '上帝', '1880-04-12', 4000, 4000, 3);

insert into emp values (20170016, '修谟', '男', 35, '哲学家', '上帝', '1768-05-14', 3000, 3000, 3);

insert into emp values (20170017, '卢梭', '男', 40, '哲学家', '上帝', '1680-06-24', 2000, 2000, 3);

insert into emp values (20170018, '蒙田', '男', 55, '哲学家', '上帝', '1553-07-04', 4000, 3000, 3);

insert into emp values (20170019, '卢克莱修', '男', 25, '哲学家', '上帝', '0503-04-24', 3000, 2000, 3);

insert into emp values (20170020, '德谟克利特', '男', 48, '哲学家', '上帝', '0020-04-12', 4000, 5000, 3);

insert into emp values (20170021, '赫拉克利特', '男', 55, '哲学家', '上帝', '0045-04-12', 5000, 5000, 3);

------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------

-- 工资等级表

create table grade

(
rank_salary int,
low_salary int,
high_salary int

);

insert into grade values (1, 7000, 9999);

insert into grade values (2, 5000, 6999);

insert into grade values (3, 2000, 4999);

------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------

-- 工资表

create table salary

(
emp_name nvarchar(16),
emp_job nvarchar(8),
emp_salary int,
emp_bonus int

);

insert into salary values ('牛顿', '物理学家',  8000, 4000);

insert into salary values ('爱因斯坦', '物理学家',  9000, 8000);

insert into salary values ('波尔', '物理学家', 6000, 4000);

insert into salary values ('薛定谔', '物理学家',  7000, 3000);

insert into salary values ('海森堡', '物理学家',  5000, 2000);

insert into salary values ('洛伦兹', '物理学家',  8000, 6000);

insert into salary values ('居里夫人', '物理学家',  8000, 8000);

insert into salary values ('拉格朗日', '数学家',  6000, 4000);

insert into salary values ('欧拉', '数学家', 8000, 6000);

insert into salary values ('罗尔', '数学家',  4000, 4000);

insert into salary values ('洛必达', '数学家', 4000, 2000);

insert into salary values ('泰勒', '数学家',  8000, 8000);

insert into salary values ('达朗贝尔', '数学家',  6000, 4000);

insert into salary values ('阿尔贝', '数学家',  4000, 3000);

insert into salary values ('康德', '哲学家',  4000, 4000);

insert into salary values ('修谟', '哲学家',  3000, 3000);

insert into salary values ('卢梭', '哲学家',  2000, 2000);

insert into salary values ('蒙田', '哲学家',  4000, 3000);

insert into salary values ('卢克莱修', '哲学家', 3000, 2000);

insert into salary values ('德谟克利特', '哲学家', 4000, 5000);

insert into salary values ('赫拉克利特', '哲学家', 5000, 5000);

------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------

--
显示每个部门的编号,部门的名称,部门员工的平均工资, 平均工资的等级。

-- 非嵌套查询

select emp.dept_id as "部门编号", dept.dept_name as "部门名称", avg(emp_salary) as "部门平均工资", grade.rank_salary as "工资等级"

from emp

join dept

on emp.dept_id = dept.dept_id

join grade

on emp.emp_salary between low_salary and high_salary

group by emp.dept_id;



-- 嵌套查询(嵌套查询产生的中间表必须取一个别名,即便别名不用,也不能省略)

select templist.dept_id as "部门编号",
templist.dept_name as "部门名称", templist.avg_sal as "部门平均工资", grade.rank_salary as "工资等级"

from
(select emp.dept_id, dept.dept_name, avg(emp.emp_salary) as "avg_sal"
from emp
join dept
on emp.dept_id = dept.dept_id
group by emp.dept_id

) as templist

join grade

on templist.avg_sal between low_salary and high_salary;



非嵌套查询出现问题,问题在哪里?

按如下步骤进行

select *

from emp

join dept

on emp.dept_id = dept.dept_id

join grade

on emp.emp_salary between low_salary and high_salary;



select *

from emp

join dept

on emp.dept_id = dept.dept_id

join grade

on emp.emp_salary between low_salary and high_salary

group by emp.dept_id;



最后进行到非嵌套查询

select emp.dept_id as "部门编号", dept.dept_name as "部门名称", avg(emp_salary) as "部门平均工资", grade.rank_salary as "工资等级"

from emp

join dept

on emp.dept_id = dept.dept_id

join grade

on emp.emp_salary between low_salary and high_salary

group by emp.dept_id;



原因在:分组后,返回结果只能是整组的信息,不能是组内具体记录的信息。sqlserver遇到这种情况就报错,但是mysql不报错,而是返回每组第一条记录。

验证:如果返回的是组信息

select emp.dept_id, avg(emp_salary)

from emp

join dept

on emp.dept_id = dept.dept_id

join grade

on emp.emp_salary between low_salary and high_salary

group by emp.dept_id;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: