Функция Max, возвращающая несколько значений [SQL] - PullRequest
0 голосов
/ 14 октября 2018

У меня 3 таблицы: деньги, студент, факультет.Этот запрос возвращает каждый факультет и самую высокую стипендию в каждом из них.

select 
    f.name as "FACULTY_NAME",
    max(stipend) as "MAX_STIPEND"
from 
    money m, student s 
inner join
    faculty f on f.id_faculty = s.faculty_id
where 
    m.student_id = s.id_student
group by 
    f.id_faculty, f.name;

Запрос работает нормально:

FACULTY_NAME     |    MAX_STIPEND
-----------------+---------------
IT Faculty       |    50
Architecture     |    60
Journalism       |    40

Однако, когда я добавляю s.name к исходному запросу, чтобы также показатьимя студента, который получил max_stipend, запрос не работает, как раньше - он возвращает всех студентов

select 
    f.name as "FACULTY_NAME",s.name,
    max(stipend) as "MAX_STIPEND"
from 
    money m, student s 
inner join
    faculty f on f.id_faculty = s.faculty_id
where 
    m.student_id = s.id_student
group by 
    f.id_faculty, f.name, s.name;

Результат запроса:

FACULTY_NAME    |   s.name  |   MAX_STIPEND
----------------+-----------+---------------
IT Faculty      |   Joe     |   50
IT Faculty      |   Lisa    |   10
Architecture    |   Bob     |   60
Journalism      |   Fred    |   5
Architecture    |   Susan   |   5
Journalism      |   Tom     |   40

Он делает то же самое, используяправый, левый и внутренний соединения.Может кто-нибудь сказать, где проблема?

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

Во-первых, вы должны использовать правильный JOIN синтаксис для всех ваших объединений.

Во-вторых, вы можете использовать синтаксис Oracle keep:

select f.name as FACULTY_NAME,
       max(stipend) as MAX_STIPEND,
       max(s.name) keep (dense_rank first order by stipend desc)
from money m join
     student s 
     on  m.student_id = s.id_student join
     faculty f
     on f.id_faculty = s.faculty_id   
group by f.id_faculty, f.name;
0 голосов
/ 14 октября 2018

Однако, когда я добавляю s.name к исходному запросу, чтобы также показать имя студента, получившего max_stipend, запрос не работает, как раньше - он возвращает всех студентов

Когда вы добавляете s.name, вы ищете минимальное значение для каждого пользователя.

Если вам нужно имя пользователя с MAX_STIPEND, вам следует перейти к оконным функциям.Например, Dense Rank в MS SQL Server.

with cte as
(select 
    f.name as "FACULTY_NAME",
    s.name as "STUDENT_NAME",
    stipend as "MAX_STIPEND",
    DENSE_RANK() OVER   
    (PARTITION BY f.name, s.name ORDER BY i.stipend DESC) AS Rank  
 from 
    money m 
 inner join student s on m.student_id = s.id_student
 inner join
    faculty f on f.id_faculty = s.faculty_id
)
select "FACULTY_NAME", "STUDENT_NAME"
from cte
where rank = 1

Не у всех брендов sql есть оконные функции.Здесь ссылка для dens_rank на MySQL , а также dens_Rank для Oracle

...