简体   繁体   中英

Oracle SQL sub query

I have a practice that I should find the employees who earn more than average salary and works in the departments with employees whose last name contains the letter u

the select statement I have used was

SELECT employee_id,
       last_name,
       salary
  FROM employees
 WHERE salary > (SELECT AVG(salary)
                   FROM employees )
   AND department_id IN(SELECT department_id
                          FROM employees
                         WHERE LOWER(last_name) LIKE '%u%')

Could anyone check this statement is suitable or not?

thank you

That looks fine to me, assuming you mean the average salary across all departments in the database, and all employees (active or not) across all of time.

I would think you might be more interested in all active employees in this current financial year, for example.

You haven't provided the schema, so be careful to check for conditions like:

  • inactive departments
  • inactive / terminated employees
  • period you are interested in for comparing the salary

Your queries looks like it will work. You can rewrite it to remove all the sub-queries (that will require additional table/index scans) and just use analytic queries:

SELECT employee_id,
       last_name,
       salary
FROM   (
  SELECT employee_id,
         last_name,
         salary,
         AVG( salary ) OVER () AS avg_salary,
         COUNT( CASE WHEN LOWER( last_name ) LIKE '%u%' THEN 1 END )
           OVER ( PARTITION BY department_id ) AS num_last_name_with_u
  FROM   employees
)
WHERE  salary > avg_salary
AND    num_last_name_with_u > 0;

db<>fiddle

My first Question are you getting the expected result?

Let me break down your Query

SELECT department_id FROM employees WHERE LOWER(last_name)

Here you are selecting the department so it retrieve the department id, what is the need of selecting department Id when all you need employee_id with last name contains u so change it to employee_id instead of department_id

select avg(salary) over (partition by department_id order by employee_id) 

So using partition by you must get the avg salary per department

SELECT employee_id,last_name,salary 
FROM 
employees 
WHERE salary>(SELECT AVG(salary) OVER (PARTITION BY department_id)
FROM 
employees ) 
AND employee_id IN
( SELECT employee_id 
FROM 
employees 
WHERE  LOWER(last_name) LIKE '%u%')

Let me know if you have any issues running it, any corrections to Query is appreciated

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM