как подсчитать разные значения из разных кортежей в одну и ту же sceme в sql

#sql #database #oracle

#sql #База данных #Oracle

Вопрос:

У меня есть таблица сведений о больницах, связанных с ней сведений о подразделениях, типы работников (персонал) в разных таблицах и информация об их заработной плате.

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

Я создал это представление всей информации о заработной плате работников:

     CREATE VIEW workers AS
    SELECT hospcod, docsal as sal, 'treatdoc' as typework
    FROM doc NATURAL JOIN treatdoc NATURAL JOIN dept
    UNION
    SELECT hospcod, nursal, 'nurse'
    FROM nurse  NATURAL JOIN dept
    UNION
    SELECT hospcod, docsal, 'rsrchdoc'
    FROM doc NATURAL JOIN rsrchdoc NATURAL JOIN lab;
 

в отделениях и лабораториях есть столбец кода больницы для сопоставления информации о работнике с конкретной больницей.
итак, у меня есть одна схема для всего персонала с их правилами workers(hospital_code, salary, type_of_worker)

вот запрос, который я пытаюсь создать:

     SELECT hospname, sum(workers.sal), avg(workers.sal), count(dept.numbed),
    (SELECT count(typework) from workers where typework = 'nurse') nurse_num,
    (SELECT count(typework) from workers where typework = 'rsrchdoc') rsrchdoc_num
    FROM hosp NATURAL JOIN dept NATURAL JOIN workers
    GROUP BY hospname;
 

Я хочу подсчитать для каждой больницы количество nurses и количество, research doctors
но это должно быть как-то соотнесено с разными hospitals (в приведенном выше это дает мне одинаковое количество медсестер / rsrchdocs для каждой больницы), должны быть столбцы, сгруппированные по именам госпиталей, и должны быть все кортежи, такие какинформация о зарплате (среднее значение, сумма), как я правильно понял, но информация о работниках должна быть сгруппирована HAVING typework = 'nurse' для nurse_num , а для столбца rsrchdoc_num она должна быть HAVING typework = 'rsrchdoc_num'

у кого-нибудь есть идея, как я могу объединить столбцы thouse в одном запросе?

Спасибо!

Комментарии:

1. Предоставьте образцы данных и желаемые результаты.

Ответ №1:

В вашем запросе есть ошибка, я постараюсь объяснить.

Когда вы это сделаете:

 (SELECT count(typework) from workers where typework = 'nurse') nurse_num,
 

Вы получаете константу, на которую не влияет «группировка по», которую вы делаете после.

Что вам нужно сделать, это ОБЪЕДИНИТЬ (как вы сделали в представлении) и связать медсестру и rsrchdoc с конкретной больницей. Я приведу пример псевдокода

 SELECT hosp_name, sum(nurse.salary) , avg(nurse.salary)
FROM hosp
JOIN nurse ON nurse.hosp_name = hosp.hosp_name
GROUP BY hosp.hosp_name
 

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

Затем вам нужно сделать то же самое и для врачей, в другой операции.

 SELECT hosp_name, sum(doctors.salary) , avg(doctors.salary)
FROM hosp
JOIN doctors ON doctors.hosp_name = hosp.hosp_name
GROUP BY hosp.hosp_name
 

И, наконец, вам придется объединить оба (вы можете сначала выполнить суммирование, чтобы сделать его более читаемым.

 SELECT hosp_name, sum_sal_doc, avg_sal_doc, sum_nur_doc, avg_nur_doc
FROM hosp
LEFT JOIN ( SELECT doctors.hosp_name, sum(doctors.salary) as sum_sal_doc, avg(doctors.salary) as avg_sal_doc
  FROM doctors
  GROUP BY doctors.hosp_name
) t1 ON t1.hosp_name = hosp.hosp_name
LEFT JOIN ( SELECT nurses.hosp_name, sum(nurses.salary) as sum_nur_doc, avg(nurses.salary) as avg_nur_doc
  FROM nurses
  GROUP BY nurses.hosp_name
) t2 ON t2.hosp_name = hosp.hosp_name
 

Ответ №2:

1 to many Между hosp --> dept и hosp --> workers поэтому, если вы присоединитесь к этим 3 таблицам, вы обязательно найдете дубликаты для dept и workers поэтому вам необходимо создать подзапрос для одного из dept или workers для извлечения одной сгруппированной записи group by больницы следующим образом:

 SELECT h.hospname, 
       sum(w.sal) total_all_worker_sal, 
       avg(w.sal) avg_all_workers_sal, 
       d.numbed,
       count(case when w.typework = 'nurse' then 1 end) nurse_num,
       count(case when w.typework = 'rsrchdoc' then 1 end) rsrchdoc_num
  FROM hosp h 
  JOIN (select hospital_code , sum(numbed) numbed 
        -- used SUM as numbed must be number of bed in department
        -- COUNT will give you only number of department if you use count(d.numbed)
          from dept 
        group by hospital_code) d ON h.hospital_code = d.hospital_code 
  JOIN workers w ON h.hospital_code = d.hospital_code
 GROUP BY h.hospital_code , h.hospname, d.numbed; 
 -- used h.hospital_code to separate the records if two hospitals have same name