加入来自不同列的相同 table 的多个计数?
Joining multiple counts on the same table, from different columns?
我觉得这应该很容易,但已经晚了,我正在挣扎。
说(在 oracle 12 db 中)我有一个 table,它表示在不同的事件期间,哪个员工在酒吧中担任什么角色,如下所示:
+----------+----------+-------+------------+----------+
| 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 个作为门卫。
(假设没有两个员工同名,也没有人可以同时做两份工作)
我该怎么做?
一个 'role' 很明显:
select count(event_id), bar group by bar
但是有没有一种优雅的方法可以对所有列执行此操作 - 无需完全连接和字符串连接?
谢谢!
您应该更改数据结构,因此每个 event/person/role 一行。那么你可以只使用聚合。
您也可以在查询中执行此操作:
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。然后使用横向join/cross apply:
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;
您可以 count 嵌套内部查询中的字符串列,然后 sum 它们 up 外面有你想要的 order :
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
我觉得这应该很容易,但已经晚了,我正在挣扎。
说(在 oracle 12 db 中)我有一个 table,它表示在不同的事件期间,哪个员工在酒吧中担任什么角色,如下所示:
+----------+----------+-------+------------+----------+
| 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 个作为门卫。
(假设没有两个员工同名,也没有人可以同时做两份工作)
我该怎么做?
一个 'role' 很明显:
select count(event_id), bar group by bar
但是有没有一种优雅的方法可以对所有列执行此操作 - 无需完全连接和字符串连接?
谢谢!
您应该更改数据结构,因此每个 event/person/role 一行。那么你可以只使用聚合。
您也可以在查询中执行此操作:
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。然后使用横向join/cross apply:
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;
您可以 count 嵌套内部查询中的字符串列,然后 sum 它们 up 外面有你想要的 order :
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