數據庫筆試——查出各部門超出部門平均薪資的員工的姓名,薪資,所在部門名稱及部門平均薪水

  有一段時間沒作數據庫的題了,前面面試偶然作到這麼一題目,以爲不錯,憑記憶將題目記下來,而後在數據庫中實現了一遍。面試

  題目大概是這樣: 一張員工表 employee,包含字段 id,name,salary,dep_no; 一張部門信息表 department,包含字段 id,dep_no,name,其中 employee 的 dep_no 關聯 department 的 dep_no;寫 sql 查出各部門超出部門平均薪資的員工的姓名,薪資,所在部門名稱及部門平均薪水。sql

  下面是我建立的兩張表:數據庫

DROP TABLE IF EXISTS department;
CREATE TABLE department (
id int NOT NULL auto_increment PRIMARY KEY,
dep_no int NOT NULL,
`name` VARCHAR(50) NOT NULL
);
INSERT INTO department(dep_no,name) VALUES(10,'研發部');
INSERT INTO department(dep_no,name) VALUES(20,'測試部');
INSERT INTO department(dep_no,name) VALUES(30,'財務部');

DROP TABLE IF EXISTS employee;
CREATE TABLE employee (
`id`  int NOT NULL auto_increment,
`name`  varchar(50) NOT NULL ,
`salary` double(10,2) NOT NULL DEFAULT 0,
`dep_no` INTEGER NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO employee(name,salary,dep_no) SELECT 'Bruce',15000.00,dep_no FROM department WHERE `name` = '研發部';
INSERT INTO employee(name,salary,dep_no) SELECT 'Kevin',16000.00,dep_no FROM department WHERE `name` = '研發部';
INSERT INTO employee(name,salary,dep_no) SELECT 'Lww',12000.00,dep_no FROM department WHERE `name` = '財務部';
INSERT INTO employee(name,salary,dep_no) SELECT 'Linda',10000.00,dep_no FROM department WHERE `name` = '財務部';
INSERT INTO employee(name,salary,dep_no) SELECT 'David',10000.00,dep_no FROM department WHERE name = '測試部';
INSERT INTO employee(name,salary,dep_no) SELECT 'Sandy',8000.00,dep_no FROM department WHERE name = '測試部';
INSERT INTO employee(name,dep_no) SELECT 'Dennis' ,dep_no FROM department WHERE name = '測試部';

  題目的分析:首先要獲得目標員工的姓名,薪資不用說要從 employee 表中得到;至於後兩個數據部門名稱及部門平均薪資,直接查 department 確定得不到,須要兩表聯立查詢,不妨就寫出這塊的 sql :測試

SELECT AVG(e.salary) AS avg_sal,d.dep_no,d.`name`
FROM employee e,department d 
WHERE d.dep_no = e.dep_no
GROUP BY d.dep_no,d.`name`;

  這裏之因此 dep_no,name兩個字段做爲分組字段,是由於後面的查詢目標中有 name,而 dep_no 做爲部門的一個惟一標識,它是自然的分組字段,同時考慮到這一部中查詢結果要與 employee 表聯立,而二者之又只能以 dep_no 鏈接,而通常狀況下不會出現一個部門對應多個部門號的狀況,因此 group by dep_no 與 group by dep_no,name 正常狀況下結果應該是同樣的。spa

  將上面的結果做爲臨時表 tmp 放入主查詢,最終獲得:code

SELECT e.`name`,e.salary,tmp.dep_name,tmp.avg_sal FROM employee e,(
SELECT AVG(e.salary) AS avg_sal,d.dep_no,d.`name` AS dep_name
FROM employee e,department d 
WHERE d.dep_no = e.dep_no
GROUP BY d.dep_no,d.`name`
)tmp WHERE e.dep_no = tmp.dep_no
AND e.salary > tmp.avg_sal;

  固然,若是真的存在一個 name 對應多個 dep_no 或者說存在不一樣部門取同一個名稱的狀況 ,那麼也可用下面的方式獲得正確結果:blog

SELECT e.`name`,e.salary,d.`name` AS dep_name,tmp.avg_sal FROM employee e,department d,(
SELECT AVG(e.salary) AS avg_sal,d.dep_no
FROM employee e,department d 
WHERE d.dep_no = e.dep_no
GROUP BY d.dep_no
)tmp WHERE e.dep_no = tmp.dep_no AND e.dep_no = d.dep_no
AND e.salary > tmp.avg_sal;

  仍是將 dep_no 做爲惟一分組字段,外層查詢再關聯 department 就好了。rem

  

  PS: 搜了一圈,好像其餘地方也有相似這樣的題目,但我以爲我作的這一版仍是很細緻的,頗有參考價值。class

相關文章
相關標籤/搜索