Показывать только одну строку на заголовок в запросе SQL - PullRequest
0 голосов
/ 25 апреля 2020

У меня следующий запрос:

select distinct p.title, e.first_name, e.last_name, max(e.salary)
 from employees as e
 inner join employees_projects as ep
 on e.id = ep.employee_id
 inner join projects as p
 on p.id = ep.project_id
 group by 1,2,3
 order by p.title

, который возвращает несколько строк на заголовок. Я хочу только максимальную зарплату за каждый титул.

          title           | first_name | last_name |  max  
--------------------------+------------+-----------+-------
 Build a cool site        | Cailin     | Ninson    | 30000
 Build a cool site        | Ian        | Peterson  | 80000
 Build a cool site        | Mike       | Peterson  | 20000
 Design 3 New Silly Walks | Ava        | Muffinson | 10000
 Update TPS Reports       | John       | Smith     | 20000

Подправлен @ ревностный код, и это работает:

 select
    title,
    first_name, 
    last_name,
    salary
from
(select 
    distinct p.title, 
    e.first_name, 
    e.last_name,
    e.salary,
    dense_rank() over (partition by p.title order by e.salary desc) as rnk
 from employees as e
 inner join employees_projects as ep
 on e.id = ep.employee_id
 inner join projects as p
 on p.id = ep.project_id
 group by 1,2,3, 4
 ) t
 where rnk = 1
 order by title

Ответы [ 3 ]

2 голосов
/ 25 апреля 2020

Предполагая, что вы хотите одну строку на заголовок, затем используйте distinct on:

select distinct on (p.title) p.title, e.first_name, e.last_name, e.salary
from employees e join
     employees_projects ep
     on e.id = ep.employee_id join
     projects p
     on p.id = ep.project_id
order by title, salary desc;

Если у вас может быть несколько заголовков, то вы можете использовать rank() или dense_rank() в подзапросе:

select title, first_name, last_name, salary
from (select p.title, e.first_name, e.last_name, e.salary,
             rank() over (partition by p.title order by e.salary desc) as seqnum
      from employees e join
           employees_projects ep
           on e.id = ep.employee_id join
           projects p
           on p.id = ep.project_id
     ) p
where seqnum = 1
order by title;
2 голосов
/ 25 апреля 2020

Попробуйте эту оконную функцию dense_rank(). Если в зарплате есть t ie, то она вернет обе записи с максимальной зарплатой.

Если вам нужна только одна запись с максимальной зарплатой, используйте row_number().

select
    title,
    first_name, 
    last_name,
    salary
from
(select 
    distinct p.title, 
    e.first_name, 
    e.last_name,
    salary,
    dense_rank() over (partition by title order by salary desc) as rnk
 from employees as e
 inner join employees_projects as ep
 on e.id = ep.employee_id
 inner join projects as p
 on p.id = ep.project_id
 group by 1,2,3
 ) t
 where rnk = 1
 order by title
0 голосов
/ 25 апреля 2020

Это в основном тот случай, когда можно использовать группу по группам, что означает, что вы хотите группировать без потери всех столбцов.

Вы можете просто использовать ниже

   Select * from (
  select distinct p.title, e.first_name, 
   e.last_name,  e.salary
   , rank()
   Over(partition by 1 order by 
    e.salary desc) 
     ) rn

   from employees as e
   inner join employees_projects as ep
   on e.id = ep.employee_id
   inner join projects as p
   on p.id = ep.project_id) 
  Where rn=1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...