我在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
另一张表是T_STATUS,其中包含以下数据:
Person_ID | Status
-------------------
101 Active
102 Active
103 Inactive
104 Active
105 Active
106 Inactive
107 Active
108 Active
109 Inactive
我正在努力获得活跃的员工和经理人数;按位置分组在一个查询中,以便结果如下:
Location | MANAGER COUNT | EMPLOYEE COUNT
Delhi 1 1
Mumbai 1 1
Noida 0 1
我正在尝试以下查询,但没有结果:
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')
......我迷路了
有人可以指导我吗?
答案 0 :(得分:4)
根据您的数据,我会这样查询:
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
与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 b.id = 'active' OR b.id IS NULL
这样的where子句 - 而且&# 39;只是丑陋。如果将常量的比较放在ON子句中,则可以跳过or ... is null
丑陋
我们按地点分组,但我们不一定会计算所有内容。如果我们计算CASE WHEN role = 'Manager' THEN ...
的结果,那么为管理器生成1的情况,并且它为非管理器生成NULL(我没有为else指定任何内容;这是设计行为的在这种情况下的情况)。这个数字也不一定是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,
它们都作为计数工作,但在SUM情况下,如果要将输出数作为计数,则确实必须使用1和0。实际上,0是可选的,因为SUM不会对空值求和(但正如下面的算法指出的那样,如果你没有将ELSE设为0,那么当有0个项时,SUM方法会产生NULL,而不是一个0.这对你来说是有帮助的还是阻碍你的决定
我还不清楚经理是否也是员工。对我来说,他们可能不是你。我添加了一个COUNT(*)字面计算该位置的每个人。任何差异意味着count_employees + count_managers!= count_everyone意味着表中还有另一个角色,而不是经理或员工..选择你的毒药
此COUNT/SUM(CASE WHEN...)
模式对于转换数据非常有用 - 一个PIVOT操作。它需要一列数据:
Manager
Employee
Manager
并将其分为两列,用于计数值:
Manager Employee
2 1
您可以根据需要多次扩展它。如果您有10个角色,则生成10个案例,结果将有10个列,并且具有分组计数。数据从row-ar表示转换为column-ar表示