牛客网数据开发题库_数据库刷题—牛客网(21-30)
21.查找所有員工自入職以來的薪水漲幅情況,給出員工編號emp_no以及其對應的薪水漲幅growth,并按照growth進行升序
CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NOT NULL, `first_name` varchar(14) NOT NULL, `last_name` varchar(16) NOT NULL, `gender` char(1) NOT NULL, `hire_date` date NOT NULL, PRIMARY KEY (`emp_no`)); CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`));輸入描述:
無思路:先分別用兩次LEFT JOIN左連接employees與salaries,建立兩張表, 分別存放員工當前工資(sCurrent)與員工入職時的工資(sStart), 再用INNER JOIN連接sCurrent與sStart,最后限定在同一員工下用當前工資減去入職工資。 法一:內層用LEFT JOIN,外層用INNER JOIN(內層也可以改用 INNER JOIN) SELECT sCurrent.emp_no, (sCurrent.salary-sStart.salary) AS growth FROM (SELECT s.emp_no, s.salary FROM employees e, salaries s WHERE e.emp_no = s.emp_no AND s.to_date = '9999-01-01') AS sCurrent INNER JOIN(SELECT s.emp_no, s.salary FROM employees e, salaries s WHERE e.emp_no = s.emp_no AND s.from_date = e.hire_date) AS sStart ON sCurrent.emp_no = sStart.emp_no ORDER BY growth; 法二:內外都層用FROM并列查詢 SELECT sCurrent.emp_no, (sCurrent.salary-sStart.salary) AS growth FROM (SELECT s.emp_no, s.salary FROM employees e, salaries s WHERE e.emp_no = s.emp_no AND s.to_date = '9999-01-01') AS sCurrent,(SELECT s.emp_no, s.salary FROM employees e, salaries s WHERE e.emp_no = s.emp_no AND s.from_date = e.hire_date) AS sStart WHERE sCurrent.emp_no = sStart.emp_no ORDER BY growth;22.統計各個部門對應員工漲幅的次數總和,給出部門編碼dept_no、部門名稱dept_name以及次數sum
CREATE TABLE `departments` ( `dept_no` char(4) NOT NULL, `dept_name` varchar(40) NOT NULL, PRIMARY KEY (`dept_no`)); CREATE TABLE `dept_emp` ( `emp_no` int(11) NOT NULL, `dept_no` char(4) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`dept_no`)); CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`));輸入描述:
無SELECT dt.dept_no,dt.dept_name,COUNT(salary) AS SUM FROM dept_emp de LEFT JOIN departments dt ON de.dept_no=dt.dept_noLEFT JOIN salaries s ON de.emp_no=s.emp_no GROUP BY dt.dept_no,dt.dept_name;23.對所有員工的當前(to_date='9999-01-01')薪水按照salary進行按照1-N的排名,相同salary并列且按照emp_no升序排列
CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`));輸入描述:
無法一-SQL Server數據庫中開窗函數(未通過): 1. SELECT emp_no,salary,rank() over(order by salary ASC) as rank FROM salary WHERE to_date='9999-01-01' ORDER BY emp_no; 2. SELECT emp_no, salaries, DENSE_RANK() OVER(ORDER BY salary DESC) AS rank WHERE to_date = '9999-01-01' ORDER BY salary DESC, emp_no ASC; 法二:復用salaries表進行比較排名 1、從兩張相同的salaries表(分別為s1與s2)進行對比分析,先將兩表限定條件設為to_date = '9999-01-01',挑選出當前所有員工的薪水情況。 2、本題的精髓在于 s1.salary <= s2.salary,意思是在輸出s1.salary的情況下, 有多少個s2.salary大于等于s1.salary, 比如當s1.salary=94409時,有3個s2.salary(分別為94692,94409,94409)大于等于它, 但由于94409重復,利用COUNT(DISTINCT s2.salary)去重可得工資為94409的rank等于2。其余排名以此類推。 3、千萬不要忘了GROUP BY s1.emp_no,否則輸出的記錄只有一條(可能是第一條或者最后一條,根據不同的數據庫而定), 因為用了合計函數COUNT() 4、最后先以 s1.salary 逆序排列,再以 s1.emp_no 順序排列輸出結果 SELECT s1.emp_no, s1.salary, COUNT(DISTINCT s2.salary) AS rank FROM salaries AS s1, salaries AS s2 WHERE s1.to_date = '9999-01-01' AND s2.to_date = '9999-01-01' AND s1.salary <= s2.salary GROUP BY s1.emp_no ORDER BY s1.salary DESC, s1.emp_no ASC;24.獲取所有非manager員工當前的薪水情況,給出dept_no、emp_no以及salary ,當前表示to_date='9999-01-01'
CREATE TABLE `dept_emp` ( `emp_no` int(11) NOT NULL, `dept_no` char(4) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`dept_no`)); CREATE TABLE `dept_manager` ( `dept_no` char(4) NOT NULL, `emp_no` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`dept_no`)); CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NOT NULL, `first_name` varchar(14) NOT NULL, `last_name` varchar(16) NOT NULL, `gender` char(1) NOT NULL, `hire_date` date NOT NULL, PRIMARY KEY (`emp_no`)); CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`));輸入描述:
無重點:表連接,NOT IN SELECT de.dept_no, s.emp_no, s.salary FROM (employees AS e INNER JOIN salaries AS s ON s.emp_no = e.emp_no AND s.to_date = '9999-01-01') INNER JOIN dept_emp AS de ON e.emp_no = de.emp_no WHERE de.emp_no NOT IN (SELECT emp_no FROM dept_manager WHERE to_date = '9999-01-01');25.獲取員工其當前的薪水比其manager當前薪水還高的相關信息,當前表示to_date='9999-01-01',
結果第一列給出員工的emp_no,
第二列給出其manager的manager_no,
第三列給出該員工當前的薪水emp_salary,
第四列給該員工對應的manager當前的薪水manager_salary
輸入描述:
無思路:創建兩張表(一張記錄當前所有員工的工資,另一張只記錄部門經理的工資)進行比較 1、先用INNER JOIN連接salaries和demp_emp,建立當前所有員工的工資記錄sem 2、再用INNER JOIN連接salaries和demp_manager,建立當前所有員工的工資記錄sdm 3、最后用限制條件sem.dept_no = sdm.dept_no AND sem.salary > sdm.salary找出同一部門中工資比經理高的員工, 并根據題意依次輸出emp_no、manager_no、emp_salary、manager_salary SELECT sem.emp_no AS emp_no, sdm.emp_no AS manager_no, sem.salary AS emp_salary, sdm.salary AS manager_salary FROM (SELECT s.salary, s.emp_no, de.dept_no FROM salaries s INNER JOIN dept_emp de ON s.emp_no = de.emp_no AND s.to_date = '9999-01-01' ) AS sem, (SELECT s.salary, s.emp_no, dm.dept_no FROM salaries s INNER JOIN dept_manager dm ON s.emp_no = dm.emp_no AND s.to_date = '9999-01-01' ) AS sdm WHERE sem.dept_no = sdm.dept_no AND sem.salary > sdm.salary;26.匯總各個部門當前員工的title類型的分配數目,結果給出部門編號dept_no、dept_name、其當前員工所有的title以及該類型title對應的數目count
CREATE TABLE `departments` ( `dept_no` char(4) NOT NULL, `dept_name` varchar(40) NOT NULL, PRIMARY KEY (`dept_no`)); CREATE TABLE `dept_emp` ( `emp_no` int(11) NOT NULL, `dept_no` char(4) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`dept_no`)); CREATE TABLE IF NOT EXISTS `titles` ( `emp_no` int(11) NOT NULL, `title` varchar(50) NOT NULL, `from_date` date NOT NULL, `to_date` date DEFAULT NULL);輸入描述:
無思路:用GROUP BY同時對 de.dept_no 和 t.title 進行分組, 1、先用 INNER JOIN 連接 dept_emp 與 salaries,根據測試數據添加限定條件 de.to_date = '9999-01-01' AND t.to_date = '9999-01-01',即當前員工的當前頭銜 2、再用 INNER JOIN 連接departments,限定條件為 de.dept_no = dp.dept_no,即部門編號相同 3、最后用 GROUP BY 同時對 de.dept_no 和 t.title 進行分組, 用 COUNT(t.title) 統計相同部門下相同頭銜的員工個數 SELECT de.dept_no, dp.dept_name, t.title, COUNT(t.title) AS count FROM titles AS t INNER JOIN dept_emp AS de ON t.emp_no = de.emp_no AND de.to_date = '9999-01-01' AND t.to_date = '9999-01-01' INNER JOIN departments AS dp ON de.dept_no = dp.dept_no GROUP BY de.dept_no, t.title;27.給出每個員工每年薪水漲幅超過5000的員工編號emp_no、薪水變更開始日期from_date以及薪水漲幅值salary_growth,并按照salary_growth逆序排列。
提示:在sqlite中獲取datetime時間對應的年份函數為strftime('%Y', to_date)
CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`));輸入描述:
無每年?? 正確答案: SELECT s2.emp_no, s2.from_date, (s2.salary - s1.salary) AS salary_growth FROM salaries AS s1, salaries AS s2 WHERE s1.emp_no = s2.emp_no AND salary_growth > 5000 AND (strftime("%Y",s2.to_date) - strftime("%Y",s1.to_date) = 1 OR strftime("%Y",s2.from_date) - strftime("%Y",s1.from_date) = 1 ) ORDER BY salary_growth DESC;28.查找描述信息中包括robot的電影對應的分類名稱以及電影數目,而且還需要該分類對應電影數量>=5部
CREATE TABLE IF NOT EXISTS film ( film_id smallint(5) NOT NULL DEFAULT '0', title varchar(255) NOT NULL, description text, PRIMARY KEY (film_id));CREATE TABLE category ( category_id tinyint(3) NOT NULL , name varchar(25) NOT NULL, `last_update` timestamp, PRIMARY KEY ( category_id ));CREATE TABLE film_category ( film_id smallint(5) NOT NULL, category_id tinyint(3) NOT NULL, `last_update` timestamp);思路:1、找到對應電影數量>=5的所有分類,建立成虛表cc: (select category_id, count(film_id) as category_num from film_category group by category_id having count(film_id)>=5) as cc 2、設定限制條件 f.description like '%robot%' 3、在表cc、f、fc、c中查找包括robot的電影對應的分類名稱和對應的電影數目。 SELECT c.name, COUNT(fc.film_id) FROM (SELECT category_id, COUNT(film_id) AS category_num FROM film_category GROUP BY category_id HAVING COUNT(film_id)>=5) AS cc, film AS f, film_category AS fc, category AS c WHERE f.description LIKE '%robot%' AND f.film_id = fc.film_id AND c.category_id = fc.category_id AND c.category_id=cc.category_id;29.對表film、film_category,使用join查詢方式找出沒有分類的電影id以及名稱
思路:運用 LEFT JOIN連接兩表,用 IS NULL語句限定條件 SELECT f.film_id,f.title FROM film f LEFT JOIN film_category fm ON f.film_id=fm.film_id WHERE fm.category_id IS NULL;30.對表film、film_category、category,
使用子查詢的方式找出屬于Action分類的所有電影對應的title,description
SELECT title,description FROM film WHERE film_id IN (SELECT fm.film_id FROM film_category fm JOIN category c ON fm.category_id=c.category_id WHERE c.name='Action'); 多個子查詢: select f.title,f.description from film as f where f.film_id in (select fc.film_id from film_category as fc where fc.category_id in (select c.category_id from category as c where c.name = 'Action'));總結
以上是生活随笔為你收集整理的牛客网数据开发题库_数据库刷题—牛客网(21-30)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吉利汽车“几何 E 萤火虫”正式上市,售
- 下一篇: 京东高管解读 Q2 财报:今年最重要的