简体   繁体   中英

SQL select values for distinct id where not min value - without sub Query - Oracle SQL

I have 2 tables

Departments

department_id, department_name

and

Employees

Employee_id, job_id, salary, department_id

For every group of department_id and Job_id i need to show all values higher than the min value without using a sub-select . How might i do this. Here is my current code. Currently has some other stuff in it as well.

SELECT e.department_id, e.job_id, e.salary
    FROM employees e JOIN departments d ON e.department_id = 
          d.department_id
    WHERE UPPER (e.job_id) NOT LIKE '%REP' AND 
          UPPER(d.department_name) NOT LIKE 'IT'
          AND UPPER(d.department_name) NOT LIKE 'SALES' AND salary 
          != MIN(e.salary)
    GROUP BY e.department_id, e.job_id
    ORDER BY e.department_id, e.job_id;

Using CTE help you provide a result set to use in the query scope.

By this, in the following query, at the first, I provide a result set and extract the data I expected and then in I use the cte result set find the final result.

with
    cte
as
(
    select
        e.department_id, e.job_id, min(e.salary) as salary_min
    from
        employees e
    inner join
        departments d
    on
        e.department_id = d.department_id
    where
        upper(e.job_id) not like '%REP'
    and
        upper(d.department_name) not like 'IT'
    and
        upper(d.department_name) not like 'SALES'
    group by
        e.department_id, e.job_id
)
select
    e.department_id ,
    e.Employee_id   ,
    e.job_id        ,
    e.salary
from
    cte
inner join
    employees e
on
    cte.department_id = e.department_id
    and
        cte.job_id = e.job_id
    and
        e.salary > cte.salary_min

UPDATE:

This query is more optimized than before and Employee table used only once. In this query, I used a window function to extract min salary.

with
    cte
as
(
    select
        e.department_id, e.Employee_id, e.job_id, e.salary, min(e.salary) over(partition by e.department_id, e.job_id) as salary_min
    from
        employees e
    inner join
        departments d
    on
        e.department_id = d.department_id
    where
        upper(e.job_id) not like '%REP'
    and
        upper(d.department_name) not like 'IT'
    and
        upper(d.department_name) not like 'SALES'
)
select
    department_id ,
    Employee_id   ,
    job_id        ,
    salary
from
    cte
where
    salary > salary_min

I'm not sure what subselect means in this context. I would strongly advise window functions:

SELECT department_id, job_id, salary
FROM (SELECT e.department_id, e.job_id, e.salary,
             MIN(e.salary) OVER (PARTITION BY e.department_id, e.job_id)
      FROM employees e JOIN
           departments d 
           ON e.department_id = d.department_id
      WHERE UPPER (e.job_id) NOT LIKE '%REP' AND 
            UPPER(d.department_name) NOT IN ('IT', 'SALES')
     ) ed
WHERE salary > min_salary
ORDER BY department_id, job_id;

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