Объединение нескольких подсчетов в одной таблице из разных столбцов? - PullRequest
0 голосов
/ 02 июля 2018

Я чувствую, что это должно быть легко, но уже поздно, и я изо всех сил.

Скажите (в оракуле 12 дБ) У меня есть таблица, которая показывает, какие сотрудники выполняли какие роли в баре во время различных событий, например:

+----------+----------+-------+------------+----------+
| event_id | bar      | doors | cloak_room | keg_room |
+----------+----------+-------+------------+----------+
| 2        | bob      | bill  | john       | mary     |
+----------+----------+-------+------------+----------+
| 3        | bob      | bill  | mary       | kev      |
+----------+----------+-------+------------+----------+
| 4        | bob      | john  | louise     | mary     |
+----------+----------+-------+------------+----------+
| 5        | kyle     | kev   | sarah      | louise   |
+----------+----------+-------+------------+----------+
| 6        | jennifer | bob   | jay        | john     |
+----------+----------+-------+------------+----------+
| 7        | john     | bill  | mary       | steve    |
+----------+----------+-------+------------+----------+ 

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

+-------+--------+
| count | person |
+-------+--------+
| 4     | bob    |
+-------+--------+
| 4     | john   |
+-------+--------+
| 3     | bill   |
+-------+--------+
| 3     | mary   |
+-------+--------+
| 2     | kev    |
+-------+--------+
| 2     | louise |
+-------+--------+
| 1     | jay    |
+-------+--------+
| 1     | steve  |
+-------+--------+ 

Мы видим здесь, что у Боба есть счет 4 - потому что он связан с 4 различными event_id: 3 как бармен и 1 как швейцар.

(при условии, что нет двух сотрудников с одинаковыми именами, и никто не может работать на двух работах одновременно)

Как мне это сделать?

для одной «роли» ясно:

select count(event_id), bar group by bar

но есть ли элегантный способ сделать это для всех столбцов - без полных объединений и конкатов строк?

спасибо!

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Вы можете считать по строковым столбцам во вложенном внутреннем запросе, а затем сумма их вверх с желаемым порядком :

SELECT sum(count) count, person
  FROM
(
 SELECT count(event_id) count, bar person FROM mytable GROUP BY bar UNION ALL
 --> P.S. Only aliasing as "person" is enough in this upper "select" for all 
 --> four "select" statements inside the parentheses.
 SELECT count(event_id)      , doors      FROM mytable GROUP BY doors UNION ALL
 SELECT count(event_id)      , cloak_room FROM mytable GROUP BY cloak_room UNION ALL
 SELECT count(event_id)      , keg_room   FROM mytable GROUP BY keg_room
)
GROUP BY person
ORDER BY 1 desc, 2;

COUNT   PERSON
   4    bob
   4    john
   3    bill
   3    mary
   2    kev
   2    louise
   1    jay
   1    jennifer
   1    kyle
   1    mary2
   1    sarah
   1    steve

Демонстрация SQL Fiddle

0 голосов
/ 02 июля 2018

Вам следует изменить структуру ваших данных, чтобы у вас была одна строка на событие / персона / роль. Тогда вы можете просто использовать агрегацию.

Вы также можете сделать это в запросе:

select who, count(*)
from (select event_id, 'bar' as job, bar as who from t union all
      select event_id, 'doors' as job, doors as who from t union all
      select event_id, 'cloak_room' as job, cloak_room as who from t union all
      select event_id, 'keg_room' as job, keg_room as who from t
     ) jw
group by who;

Если у кого-то может быть несколько заданий в одном событии, используйте count(distinct event_id).

EDIT:

Я вижу, что вы используете Oracle 12c. Затем используйте боковое соединение / поперечное применение:

select who, count(*)
from t cross apply
     (select t.event_id, 'bar' as job, t.bar as who from dual union all
      select t.event_id, 'doors' as job, t.doors as who from dual from dual union all
      select event_id, 'cloak_room' as job, cloak_room as who from dual union all
      select t.event_id, 'keg_room' as job, t.keg_room as who from dual
     ) jw
group by who;
...