База данных сотрудников SQL-запросов

sql oracle

71 просмотра

2 ответа

Я хочу найти компанию, которая платит наименьшую общую зарплату вместе с общей заработной платой.

Детали заключаются в следующем,

works( empid, companyname, salary )

И мой запрос выглядит так,

SELECT COMPANYNAME 
FROM WORKS 
WHERE SALARY=
  (SELECT MIN(SUM(SALARY)) 
  FROM 
      (SELECT SUM(SALARY) 
      FROM WORKS 
      GROUP BY COMPANYNAME) 
GROUP BY COMPANYNAME);

но это не возвращает никаких строк.

Я новичок в SQL, поэтому я надеюсь, что вы можете ответить мне в понятной форме.

Автор: Anand AK Источник Размещён: 08.11.2019 11:15

Ответы (2)


2 плюса

Решение

Ваш запрос не возвращает никаких строк, потому что вы ищете строки в исходной таблице works. В этой таблице у вас нет общей зарплаты, выплаченной за какую-либо компанию, только зарплаты отдельных сотрудников, поэтому, конечно, запрос не будет возвращать никаких строк. Нет отдельного сотрудника, чья зарплата равна минимальной ОБЩЕЙ зарплате среди компаний.

Есть много способов решить эту проблему, но, поскольку вы новичок, вам следует искать только решения, использующие базовые операторы SQL (даже если вы не будете использовать такое решение на производстве). Ваша цель сейчас - узнать, как работает SQL, а не получить самое быстрое или самое передовое решение.

С учетом сказанного: сначала вам нужно будет создать запрос, который группирует строки по компании, а затем выберите компанию (или компании, если есть привязка к первому месту) с самой низкой общей зарплатой. Для этого вам нужно использовать GROUP BY, как вы уже сделали. Затем, чтобы выбрать из ГРУПП (не из исходных строк), вам нужно использовать HAVINGпредложение, а не WHEREпредложение. Что-то вроде этого:

select   companyname, sum(salary) as total_salary
from     works
group by companyname 
having   sum(salary) = ( select   min(sum(salary))
                         from     works
                         group by companyname
                       )
;

Также обратите внимание, что SQL позволяет вам обернуть агрегатную функцию в другую - вы можете писать select min(sum(salary))прямо против исходной таблицы. Это показано в моем подзапросе; сравните с тем, что было в вашей первоначальной попытке.

Автор: mathguy Размещён: 20.08.2016 11:59

1 плюс

Вот один метод в Oracle 12c +:

SELECT COMPANYNAME, SUM(SALARY) 
FROM WORKS 
GROUP BY COMPANYNAME
ORDER BY SUM(SALARY)
FETCH FIRST 1 ROW ONLY;

В более старых версиях, использование ROW_NUMBER(), RANK(), или DENSE_RANK(). Итак, если могут быть связи, используйте:

SELECT w.*
FROM (SELECT COMPANYNAME, SUM(SALARY) as total_salary,
             RANK() OVER (ORDER BY SUM(SALARY)) as seqnum
      FROM WORKS 
      GROUP BY COMPANYNAME
     ) w
WHERE seqnum = 1;

Это возвращает дубликаты в случае связей. Вы можете использовать, ROW_NUMBER()если хотите гарантировать, что всегда возвращается ровно одна строка.

Автор: Gordon Linoff Размещён: 20.08.2016 11:47
Вопросы из категории :
32x32