【问题标题】:Joining multiple counts on the same table, from different columns?从不同的列加入同一张表上的多个计数?
【发布时间】:2018-12-11 00:33:03
【问题描述】:

我觉得这应该很容易,但为时已晚,我正在苦苦挣扎。

假设(在 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

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

谢谢!

【问题讨论】:

    标签: sql oracle group-by aggregation unpivot


    【解决方案1】:

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

    您也可以在查询中这样做:

    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;
    

    【讨论】:

    • 感谢您的回答!您说“如果某人可以在一个事件中拥有多个工作,则使用 count(distinct event_id)”的部分。如果有可能同时从事两份工作,并且我想将在同一事件中同时从事两份工作的人在总计数中只计算一次——我会怎么做?如果我添加 'distinct event_id' 我仍然会得到相同的结果?
    【解决方案2】:

    您可以在嵌套的内部查询中按字符串列计数,然后按照您想要的顺序将它们向上 在外面 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

    【讨论】:

    • 嗨@barbaros - 非常感谢,这很有效!如果一个人有可能在一个事件中从事多项工作,(例如这个例子sqlfiddle.com/#!4/8d279/2)但我们只想计算与(不是工作工作)相关的事件 - 有没有一种简单的方法可以更改查询来做到这一点?
    • @Paul 谢谢你的朋友。据我了解,您的意思是:sqlfiddle.com/#!4/8d279/26
    • 完美运行!我不知道为什么工会让我如此困惑。非常感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    相关资源
    最近更新 更多