我在 Oracle DB 上有表 T_LOCATION_DATA,如下所示:
Person_ID | Location | Role
----------------------------
101 Delhi Manager
102 Mumbai Employee
103 Noida Manager
104 Mumbai Employee
105 Noida Employee
106 Delhi Manager
107 Mumbai Manager
108 Delhi Employee
109 Mumbai Employee
Run Code Online (Sandbox Code Playgroud)
另一个表是 T_STATUS,其中包含以下数据:
Person_ID | Status
-------------------
101 Active
102 Active
103 Inactive
104 Active
105 Active
106 Inactive
107 Active
108 Active
109 Inactive
Run Code Online (Sandbox Code Playgroud)
我正在尝试获取活跃的员工和经理的数量;在单个查询中按位置分组,结果如下:
Location | MANAGER COUNT | EMPLOYEE COUNT
Delhi 1 1
Mumbai 1 1
Noida 0 1
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用以下查询但没有结果:
select location, count (a.person_id) as MANAGER COUNT,
count (b.person_id) as EMPLOYEE COUNT
from T_LOCATION_DATA a,T_LOCATION_DATA b
where a.person_id in (select person_id from t_status where status='Active')
Run Code Online (Sandbox Code Playgroud)
......我在这里迷路了
有人可以指导我吗?
根据您的数据,我会这样查询:
SELECT
Location,
COUNT(CASE WHEN Role='Manager' THEN 1 END) as count_managers,
COUNT(CASE WHEN Role='Employee' THEN 1 END) as count_employees,
COUNT(*) count_everyone
FROM
t_location_data l
INNER JOIN
t_status s
ON
l.person_id = s.person_id AND
s.status = 'Active'
GROUP BY location
Run Code Online (Sandbox Code Playgroud)
与您的 SQL 的差异:
我们抛弃了糟糕的旧连接语法 ( SELECT * FROM a,b WHERE a.id=b.id) - 请始终使用a JOIN b ON a.id = b.id
我们加入状态表,但我们只对活动表真正这样做,因此我将其作为 ON 中的另一个子句声明的原因。我可以把它放在一个WHERE. 与INNER JOIN它没有区别。使用OUTER JOIN它可以产生很大的不同,就好像您编写的a LEFT JOIN b ON a.id = b.id WHERE b.id = 'active'内容会将 LEFT JOIN 转换回 INNER JOIN 行为,除非您创建了一个 where 子句,例如WHERE b.id = 'active' OR b.id IS NULL- 这很丑陋。如果将与常量的比较放在 ON 子句中,则可以跳过or ... is null丑陋
我们按位置分组,但我们不一定计算所有内容。如果我们计算 a 的结果CASE WHEN role = 'Manager' THEN ...,那么当为管理器产生 1 时,它为非管理器产生 NULL(我没有为 else 指定任何内容;这是 CASE WHEN 在这种情况下的设计行为) . 数字也不必是 1;可能是'a',Role;任何非空的东西。COUNT 将任何非 null 计数为 1,将 null 计数为 0。因此以下是等效的,选择对您更有意义的那个:
COUNT(CASE WHEN Role='Employee' THEN 1 END) as count_employees,
COUNT(CASE WHEN Role='Employee' THEN 'a' END) as count_employees,
COUNT(CASE WHEN Role='Employee' THEN role END) as count_employees,
COUNT(CASE WHEN Role='Employee' THEN role ELSE null END) as count_employees,
SUM(CASE WHEN Role='Employee' THEN 1 ELSE 0 END) as count_employees,
Run Code Online (Sandbox Code Playgroud)
它们都用作计数,但在 SUM 的情况下,如果您希望输出数字是计数,则确实必须使用 1 和 0。实际上,0 是可选的,因为 SUM 不会对空值求和(但正如 mathguy 在下面指出的那样,如果您没有输入 ELSE 0,那么当有 0 个项目时,SUM 方法将产生一个 NULL,而不是一个 0。这是否对您有帮助或阻碍是由您自己做出的决定)
我不清楚经理是否也是员工。对我来说,他们是,也许对你不是。我添加了一个 COUNT(*) 来计算该位置的每个人。任何差异意味着 count_employees+count_managers != count_everyone 意味着表中有另一个角色,不是经理或员工.. 选择你的毒药
这种COUNT/SUM(CASE WHEN...)模式对于翻转数据非常有用 - PIVOT 操作。它需要一列数据:
Manager
Employee
Manager
Run Code Online (Sandbox Code Playgroud)
并将其变成两列,用于计数值:
Manager Employee
2 1
Run Code Online (Sandbox Code Playgroud)
您可以根据需要多次扩展它。如果您有 10 个角色,请创建 10 个 case whens,结果将包含 10 个分组计数的列。数据从 row-ar 表示转换为 column-ar 表示
| 归档时间: |
|
| 查看次数: |
917 次 |
| 最近记录: |