在同一表格中,从不同的列连接多个计数?

时间:2018-07-02 18:33:23

标签: sql oracle

我觉得这应该很容易,但是已经晚了,我正在努力。

说(在oracle 12 db中),我有一张表,该表代表在不同事件期间哪个员工在酒吧中扮演什么角色,像这样:

+----------+----------+-------+------------+----------+
| 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  |
+-------+--------+ 

我们在这里看到bob的计数为4-因为他与4个不同的event_id相关联:3是男服务员,1是门卫。

(假设没有两个工作人员姓名相同,并且没有人一次可以工作两个工作)

我该怎么做?

对于一个“角色”,很明显:

select count(event_id), bar group by bar

但是有没有一种优雅的方法可以对所有列执行此操作-没有完全连接和字符串连接?

谢谢!

2 个答案:

答案 0 :(得分:2)

您应该更改数据的结构,因此每个事件/人/角色只有一行。然后,您可以使用聚合。

您也可以在查询中执行此操作:

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)

编辑:

我看到您正在使用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;

答案 1 :(得分:1)

您可以根据嵌套内部查询中的字符串列进行 count 计数,然后根据需要的顺序 up 在其外部 sum em>:

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 Demo