1. 程式人生 > >Orcale-SQL語句 習題-長期更新

Orcale-SQL語句 習題-長期更新

本文中,將會包含部分我做過的Orcale習題,以供參考,希望能有熱心的小夥伴,積極討論,歡迎指出錯誤,或更好的解決方法~
一、Orcale 經典習題-40題
資料庫的結構和資料都在我上傳的資源中,可以進行免費下載。(本來想免費的,結果設定不了免費,至少1分,就設定成了1分 0.0)
題目&我做的答案

--1.查詢僱傭時間在1997年之後的員工資訊
Select
    *
From
    employees e
Where
    1997 < extract(year from e.hire_date) ;

--2.查詢有提成的員工資訊(last name,  job, salary, and commission),並按工資降序排列。
Select last_name, job_id, salary, e.commission_pct From employees e Order by 3 desc; --3.Show the employees that have no commission with a 10% raise in their salary --(round off the salaries). -- 向沒有佣金的員工展示他們的工資增加10%(四捨五入的薪水)。 Select employee_id, first_name, last_name, salary, round(nvl2(commission_pct, salary, salary * 1.10
), 0) new_salary From employees e Where commission_pct is null;
--4.Show the last names of all employees together with the number of years --and the number of completed months that they have been employed. --顯示所有員工的姓氏以及他們被僱用的年數和完成月數。 With Q_mon As (Select employee_id, extract(month from
sysdate)-extract(month from hire_date) mon_diff From employees) Select last_name, case when mon_diff >= 0 then (extract(year from sysdate) - extract(year from hire_date)) else (extract(year from sysdate) - extract(year from hire_date) - 1) end work_year, case when mon_diff >= 0 then mon_diff else (mon_diff + 12) end work_month From employees e, Q_mon Where e.employee_id = Q_mon.employee_id;
--5. Show those employees that have a name starting with J, K, L, or M --顯示名稱以J,K,L或M開頭的員工 Select * From employees Where first_name like 'J%' union all Select * From employees Where first_name like 'K%' union all Select * From employees Where first_name like 'L%' union all Select * From employees Where first_name like 'M%'; --Select * From employees Where regexp_like(first_name,'^[J|K|L|M].*'); --6.Show all employees, and indicate with “Yes” or “No” whether they receive a commission. --顯示所有員工,並在“是”或“否”時表明他們是否收到佣金。 Select employee_id, first_name, last_name, case when commission_pct is null then 'NO' else 'YES' end whether From employees e; --7.Show the department names, locations, names, job titles, --and salaries of employees who work in location 1800. --在1800位置顯示工作的員工的部門名稱,地點,姓名,職位和工資。 Select d.department_name, d.location_id, e.first_name, e.last_name, e.job_id, e.salary From employees e, departments d Where e.department_id = d.department_id and d.location_id = 1800; --8.How many employees have a name that ends with an n? Create two possible solutions. --有多少員工的名字以n結尾? 建立兩個可能的解決方 Select count(last_name) From employees Where last_name like '%n'; Select sum(decode(substr(last_name, -1), 'n', 1, 0)) sum_number From employees; Select count(last_name) From employees Where regexp_like(last_name,'.*n$'); --9.Show the names and locations for all departments, --and the number of employees working in each department. --Make sure that departments without employees are included as well. --顯示所有部門的名稱和位置,以及每個部門的員工數量。 確保包含沒有員工的部門。 Select d.department_id, d.department_name, d.location_id, count(employee_id) From departments d left join employees e on d.department_id = e.department_id Group by d.department_id, d.department_name, d.location_id Order by 1 ; --10.Which jobs are found in departments 10 and 20? --在部門10和20中找到哪些工作? Select job_id From employees e Where e.department_id = 10 Union Select job_id From employees e Where e.department_id = 20; --11.Which jobs are found in the Administration and Executive departments, --and how many employees do these jobs? Show the job with the highest frequency first. --在行政和執行部門找到了哪些工作,有多少員工從事這些工作? 首先顯示頻率最高的作業。 Select job_id, count(employee_id) From employees e left join departments d on e.department_id = d.department_id Where upper(d.department_name) in (upper('Administration'), upper('Executive')) Group by job_id Order by 2 desc; --12.Show all employees who were hired in the first half of the month (before the 16th of the month). --顯示在本月上半月(本月16日之前)被僱用的所有員工。 Select employee_id, last_name, hire_date From employees e Where extract(day from hire_date) < 16; --13. Show the names, salaries, and the number of dollars (in thousands) that all employees earn. --顯示所有員工的姓名,賺取的工資和美元數(以千計)。 Select first_name, last_name, to_char(salary, 'L9,999,000,00') From employees e; --14.Show all employees who have managers with a salary higher than $15,000. --Show the following data: employee name, manager name, manager salary, and salary grade of the manager. --顯示所有經理薪水高於15,000美元的員工。 顯示以下資料:員工姓名,經理姓名,經理薪水和工資等級。 Select e.first_name ||' '||e.last_name employee_name, e1.first_name ||' '||e1.last_name manager_name, e1.salary, (case when e1.salary < 5000 then 'A' when e1.salary < 10000 then 'B' when e1.salary < 15000 then 'C' when e1.salary < 20000 then 'D' else 'E' end) salary_level From employees e left join employees e1 on e1.employee_id = e.manager_id Where e1.salary > 15000 ; --15. Show the department number, name, number of employees, and average salary of all departments, -- together with the names, salaries, and jobs of the employees working in each department. --顯示所有部門的部門編號,姓名,員工人數和平均工資,以及每個部門工作人員的姓名,工資和工作。 Select d.department_id , department_name, /*(select count(*) From employees e Where e.department_id = d.department_id Group by e.department_id) sum_number, (Select Round( avg(salary), 2) From employees e1 Where e1.department_id = d.department_id Group by e1.department_id) avg_salary,*/ count(*) over (partition by e2.department_id) sum_number, Round( avg(salary) over (partition by e2.department_id), 2 ) avg_salary, last_name, salary, job_id From departments d left join employees e2 on d.department_id = e2.department_id; Select nvl2(lag(d.department_id, 1, null) over (partition by e2.department_id order by null),null, d.department_id), nvl2(lag(d.department_name, 1, null) over (partition by d.department_name order by null),null, d.department_name), -- nvl2(lag(), 1, null) -- over (partition by (count(*) over (partition by e2.department_id)) order by null),null, d.department_id), d.department_id , department_name, count(*) over (partition by e2.department_id) sum_number, Round( avg(salary) over (partition by e2.department_id), 2 ) avg_salary, last_name, salary, job_id From departments d left join employees e2 on d.department_id = e2.department_id ; select decode ( lag(t1.A ,1,null) over (partition by t1.A order by t1.A,t1.B,t1.C,t1.D),null,t1.A,null) A1, decode ( lag(t1.B ,1,null) over (partition by t1.A order by t1.A,t1.B,t1.C,t1.D),null,t1.B,null) A2, decode ( lag(t1.C ,1,null) over (partition by t1.A order by t1.A,t1.B,t1.C,t1.D),null,t1.C,null) A3, decode ( lag(t1.D ,1,null) over (partition by t1.A order by t1.A,t1.B,t1.C,t1.D),null,t1.D,null) A4, t1.E,t1.F,t1.G from (select distinct d.department_id A , d.department_name B, count(e.employee_id) over (partition by e.department_id ) as C, -- nvl2(avg(e.salary) over (partition by e.department_id ),to_char(),'no average') as D, nvl (to_char(avg(e.salary) over (partition by e.department_id ),'999,999,999.99'),'no average') as D, e.last_name as E, e.salary as F , e.job_id as G from departments d,employees e where d.department_id=e.department_id(+)) t1; --使用 lag 進行置空 --16.Show the department number and the lowest salary of the department with the highest average salary. --顯示平均工資最高的部門編號和最低工資。 With Q1 as (Select department_id, avg(salary) avg_salary From employees Group by department_id) Select distinct e.department_id, min(salary) over(partition by e.department_id) min_salary From employees e left join Q1 on e.department_id = Q1.department_id Where avg_salary >= (Select max(Q1.avg_salary) From Q1); --17.Show the department numbers, names, --and locations of the departments where no sales representatives work. --顯示沒有銷售代表工作的部門的部門編號,名稱和位置。 Select distinct d.department_id, d.department_name, d.location_id, d.manager_id From departments d left join employees e on d.manager_id = e.manager_id left join jobs j on e.job_id = j.job_id Where NVL2(j.job_title, upper(j.job_title), 'title_null') <> upper('Sales Representative') Order by 1; --18.Show the department number, department name, and the number of employees working in each department that: --a. Includes fewer than 3 employees: b. Has the highest number of employees: --c. Has the lowest number of employees: --18. 顯示部門名稱、編號、工作在每個部門的員工數量,分別有以下三個要求 --a小於三個員工 b員工數最多 c員工數最少 With Q1 AS (Select d.department_id, count(employee_id) sum_number From departments d left join employees e on d.department_id = e.department_id Group by d.department_id) Select department_name, d.department_id, sum_number From departments d left join Q1 on d.department_id = q1.department_id Where --q1.sum_number < 3 --q1.sum_number >= (Select max(sum_number) From Q1 ) q1.sum_number <= (Select min(sum_number) From Q1); --需要 departments 與 employees 做 左外連結 !!! --19. Show the employee number, last name, salary, department number, --and the average salary in their department for all employees. --顯示所有員工的員工編號,姓氏,工資,部門編號以及部門的平均工資。 Select e.employee_id, first_name || ' ' ||last_name employee_name, e.department_id, Round(avg(e.salary)over(partition by e.department_id) , 2) depart_salary_avg From employees e; --20.Show all employees who were hired on the day of the week --on which the highest number of employees were hired. --顯示在僱用最多僱員人數的當天僱用的所有員工。 With Q1 as (Select to_char(hire_date, 'DAY','NLS_DATE_LANGUAGE=AMERICAN') hire_day, count(employee_id) hire_sum From employees e1 Group by to_char(hire_date, 'DAY','NLS_date_language=american') Order by 2 Desc) Select first_name, last_name, to_char(hire_date, 'DAY','NLS_date_language=american') hire_day From employees e1 Where to_char(hire_date, 'DAY','NLS_date_language=american') in (Select hire_day From Q1 Where Q1.hire_sum >= (Select max(hire_sum) From Q1)) ; --21.Create an anniversary overview based on the hire date of the employees. --Sort the anniversaries in ascending order. --根據員工的僱用日期建立週年紀念概覽。 按升序排列週年紀念日。 Select first_name, last_name,to_char(hire_date, 'mm-dd') birth_hire From employees e Order by 3 ASC; Select localtimestamp From dual; --22.Find the job that was filled in the first half of 1990 --and the same job that was filled during the same period in 1991. --找到1990年上半年填補的工作和1991年同期填補的工作。 Select job_id From employees Where extract(year from hire_date) = 1990 and extract(month from hire_date) <= 6 Intersect Select job_id From employees Where extract(year from hire_date) = 1991 and extract(month from hire_date) <= 6 --23.. Write a compound query to produce a list of employees showing raise percentages, --employee IDs, and old salary and new salary increase. --Employees in departments 10, 50, and 110 are given a 5% raise, --employees in department 60 are given a 10% raise, --employees in departments 20 and 80 are given a 15% raise, --and employees in department 90 are not given a raise. --23. 顯示工資漲幅,員工編號,原來的工資和增加的工資: --部門號1050110的有5%的漲幅,部門號為60的漲10%的工資 --部門號為2080漲幅為15%,部門為90的不漲工資 Select e1.department_id, salary_by, employee_id, salary, salary * (1 + salary_by) From employees e1 left join (Select department_id, decode(department_id, 10,0.05, 50,0.05, 100,0.05, 60,0.10, 20,0.15, 80,0.15, 0 )salary_by From employees Group by department_id) s on e1.department_id = s.department_id Order by 2 desc; --24.Alter the session to set the NLS_DATE_FORMAT to DD-MON-YYYY HH24:MI:SS. Select * from nls_session_parameters Where parameter = 'NLS_DATE_FORMAT'; --'DD-MON-RR' Select sysdate From dual; Alter session Set NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS'; --25the following time zones. --a. Australia/Sydney Chile/Easter Island SELECT TZ_OFFSET ('Australia/Sydney') from dual; SELECT TZ_OFFSET ('Chile/EasterIsland') from dual; --b. Alter the session to set the TIME_ZONE parameter value to the time zone offset of Australia/Sydney. --alter session set time_zone = '+10:00'; Alter session set time_zone = 'Australia/Sydney'; Select SYSDATE, CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP From dual; --c. Display the SYSDATE, CURRENT_DATE, CURRENT_TIMESTAMP, and LOCALTIMESTAMP for this session. --Note: The output might be different based on the date when the command is executed. SELECT SYSDATE,CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP FROM DUAL; --d. Alter the session to set the TIME_ZONE parameter value to the time zone offset of Chile/Easter Island. --alter session set time_zone = '-6:00'; Alter session set time_zone = 'Chile/EasterIsland'; Select SYSDATE, CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP From dual; --e. Display the SYSDATE, CURRENT_DATE, CURRENT_TIMESTAMP, and LOCALTIMESTAMP for this session. Select SYSDATE, CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP From dual; --f. Alter the session to set the NLS_DATE_FORMAT to DD-MON-YYYY. Alter session Set NLS_DATE_FORMAT = 'DD-MON-YYYY'; Select * from nls_session_parameters; Select * from nls_database_parameters; Select * from nls_instance_parameters; --26.Write a query to display the last names, month of the date of join, and hire date --of those employees who have joined in the month of January, irrespective of the year of join. --寫一個查詢來顯示姓氏,加入日期和僱用日期? 無論加入年份如何,在1月份加入的員工。 With Q1 as (Select count(*) sum_number, to_char(e.hire_date, 'yyyy-mm') year_mon From employees e Group by to_char(e.hire_date, 'yyyy-mm')) Select last_name, sum_number, hire_date From employees e left join Q1 on to_char(e.hire_date, 'yyyy-mm') = Q1.year_mon Where 1 = extract(month from hire_date); --27.Write a query to display the following for those departments --whose department ID is greater than 80: --The total salary for every job within a department --The total salary --The total salary for those cities in which the departments are located --The total salary for every job, irrespective of the department --The total salary for every department irrespective of the city --The total salary of the cities in which the departments are located --Total salary for the departments, irrespective of job titles and cities --編寫查詢以顯示部門ID更高的部門的以下內容? 比80: --部門內每項工作的總薪水 --總薪水 --各部門所在城市的總薪資 --每個工作的總薪水,不論部門如何 --不論城市如何,每個部門的總薪水 --各部門所在城市的總薪資 --各部門的總薪資,不論職稱和城市 Select city, department_name, job_id, sum(salary) From employees e, departments d, locations l Where l.location_id = d.location_id and d.department_id = e.department_id and d.department_id > 80 Group by cube(city, department_name, job_id) Order by 1, 2, 3; --28.. Write a query to display the following groupings: --Department ID, Job ID --Job ID, Manager ID -- The query should calculate the maximum and minimum salaries for each of these groups. --編寫查詢以顯示以下分組: --部門ID,職務ID --工作ID,經理ID -- 查詢應計算每個組的最高和最低工資。 Select department_id, job_id, manager_id, max(salary), min(salary) From employees e Group by --rollup(department_id, manager_id, job_id) grouping sets((department_id, job_id),(job_id, manager_id)) Order by 1,2,3; --29.Write a query to display the top three earners in the EMPLOYEES table. -- Display their last names and salaries. --編寫查詢以顯示EMPLOYEES表中的前三個收入者。 顯示他們的姓氏和工資。 Select last_name,salary From (Select rownum r1 , last_name, salary From employees Order by 3 desc) Q Where r1 < 4; --使用分析函式 --30.Write a query to display the employee ID and last names of the employees --who work in the state of California. --編寫查詢以顯示在加利福尼亞州工作的員工的員工ID和姓氏。 Select employee_id, last_name From employees e, departments d, locations l Where e.department_id = d.department_id and d.location_id = l.location_id and upper(l.state_province) = upper('California'); --31. Write a query to delete the oldest JOB_HISTORY row of an employee --by looking up the JOB_HISTORY table for the MIN(START_DATE) for the employee. --Delete the records of only those employees who have changed at least two jobs. --If your query executes correctly, you will get the feedback: --編寫查詢以通過查詢員工的MIN(START_DATE)的JOB_HISTORY表來刪除員工的最舊JOB_HISTORY行。 --僅刪除已更改至少兩個作業的員工的記錄。 如果您的查詢正確執行,您將獲得反饋: Delete From job_history j --Select j.* From job_history j Where /* j.employee_id = (Select Q1.employee_id From (Select employee_id, count(employee_id) change_time From job_history j1 Group by employee_id Having count(employee_id) > 1) Q1 Where Q1.employee_id = j.employee_id) and */ j.start_date = (Select min(j2.start_date) From job_history j2 Where j2.employee_id = j.employee_id having count(*) >= 2); rollback; --32.Roll back the transaction. Select job_id, job_title, min_salary, max_salary From Jobs Order by 4 desc; Insert into jobs(job_id, job_title, min_salary, max_salary) Values('My_job', 'My_title', 15000.00, 30000.00); Savepoint insert_jobs; Update jobs Set min_salary = 20000.00, max_salary = 50000.00 Where job_id = 'My_job'; Savepoint update_jobs; rollback to savepoint insert_jobs; Update jobs Set min_salary = 45000.00, max_salary = 60000.00 Where job_id = 'My_job'; Savepoint update_jobs1; rollback to savepoint update_jobs; Insert into jobs(job_id, job_title, min_salary, max_salary) Values('My_job1', 'My_title1', 15000.00, 30000.00); Savepoint insert_jobs1; rollback to savepoint update_jobs; rollback to savepoint update_jobs1; rollback ; commit; --33.Write a query to display the job IDs of those jobs --whose maximum salary is above half the maximum salary in the whole company. --Use the WITH clause to write this query. Name the query MAX_SAL_CALC. --編寫查詢以顯示最高工資高於整個公司最高工資一半的工作的工作ID。 --使用WITH子句編寫此查詢。 將查詢命名為MAX_SAL_CALC。 With Job_salary_max As (Select job_id, max(salary) job_max From employees Group by job_id), All_salary_max As (Select max(salary) * 0.50 Half_all From employees) Select job_title, job_max From Job_salary_max,All_salary_max,jobs Where Job_salary_max.job_id = jobs.job_id and Job_salary_max.job_max > All_salary_max.Half_all; --34.Write a SQL statement to display employee number, last name, start date, and salary,showing: --a. De Haan’s direct reports --b. The organization tree under De Haan (employee number 102) --編寫一個SQL語句來顯示員工編號,姓氏,開始日期和工資: --De Haan 的領導, --手下的員工 Select employee_id, first_name, last_name, hire_date, salary From employees e Start with upper(last_name) = upper('De Haan') Connect by --employee_id = prior manager_id; prior employee_id = manager_id; --35. Write a hierarchical query to display the employee number, manager number, --and employee last name for all employees who are two levels below employee De Haan --(employee number 102). Also display the level of the employee. --編寫分層查詢以顯示員工De Haan(員工編號102)以下兩級員工的員工編號, --經理編號和員工姓氏。還顯示員工的級別。 Select * From ( Select employee_id, first_name, last_name, manager_id, level employee_levles From employees e Start with upper(last_name) = upper('De Haan') Connect by prior employee_id = manager_id ) Where employee_levles > 2; --36. Produce a hierarchical report to display the employee number, manager number, --the LEVEL pseudocolumn, and employee last name. For every row in the EMPLOYEES table, --you should print a tree structure showing the employee, the employee’s manager, --then the manager’s manager, and so on. Use indentations for the NAME column. --生成分層報告以顯示員工編號,經理編號,LEVEL偽列和員工姓氏。 --對於EMPLOYEES表中的每一行,您應該列印一個樹結構,顯示員工,員工的經理, --然後是經理的經理,等等。 對NAME列使用縮排。 Select employee_id, manager_id, level, Lpad(last_name, length(last_name)-1+level, '_' ) level_name From employees e Start with employee_id = 100 Connect by prior employee_id = manager_id; select employee_id, manager_id, level, lpad(last_name, length(last_name) + level - 1, '_') from employees e start with employee_id in (select employee_id from employees start with manager_id is null connect by manager_id = prior employee_id) connect by e.employee_id = prior e.manager_id; --37.Write a query to do the following: --Retrieve the details of the employee ID, hire date, salary, and manager ID --of those employees whose employee ID is more than or equal to 200 from the EMPLOYEES table. --If the salary is less than $5,000, insert the details of employee ID and salary into the SPECIAL_SAL table. --Insert the details of employee ID, hire date, and salary into the SAL_HISTORY table. --Insert the details of employee ID, manager ID, and salary into the MGR_HISTORY table. --37. 顯示員工編號、入職時間、薪水、上司的編號,要求員工編號大於等於200 --如果薪水小於5000,將員工編號和薪水插入到SPECIAL_SAL表裡 --將員工編號、入職時間、薪水插入到SAL_HISTORY表 --將員工編號、上司編號、薪水插入到MGR_HISTORY表 Create table special_sal(employee_id number primary key, salary number) Create table sal_history(employee_id number primary key, hire_date date not null, salary number) Create table mgr_history(employee_id number primary key, manager_id number, salary number) Insert all When salary < 5000 then into special_sal values(employee_id, salary) When 1 = 1 then into sal_history values(employee_id, hire_date, salary) When 1 = 1 then into mgr_history values(employee_id, manager_id, salary) Select employee_id, hire_date, salary, manager_id From employees Where employee_id >= 200; Select * From special_sal; Select * From sal_history; Select * From mgr_history; rollback; --38.Query the SPECIAL_SAL, SAL_HISTORY and the MGR_HISTORY tables to view the inserted records. --查詢SPECIAL_SAL,SAL_HISTORY和MGR_HISTORY表以檢視插入的記錄。 Select * From special_sal; Select * From sal_history; Select * From mgr_history; --39.Create the LOCATIONS_NAMED_INDEX table based on the following table instance chart. --Name the index for the PRIMARY KEY column as LOCATIONS_PK_IDX. --39. 基於下列示意圖建立一個LOCATIONS_NAMED_INDEX表,將主鍵列作為索引並起名為LOCATIONS_PK_IDX Create table locations_named_index (Deptno number(4) constraint locations_pk_idx primary key, Dname varchar2(30) ); select t.*,i.index_type from user_ind_columns t,user_indexes i where t.index_name = i.index_name and t.table_name= Upper('locations_named_index'); drop table locations_named_index; --40.Query the USER_INDEXES table to display the INDEX_NAME for the LOCATIONS_NAMED_INDEX table. -- Select index_name From USER_INDEXES Where tabele_name = 'LOCATIONS_NAMED_INDEX';