所以我有两张桌子。一个人拥有的股份数量:
Person_ID || Shares
1 || 100
2 || 150
3 || 315
4 || 75
5 || 45
...
和另一个信息是否存在一个人(指定了两个列)以及他属于哪个组:
Person_id || barcode_presence || manual_presence || group_id
1 || NULL || 1 || NULL
2 || 1 || NULL || 1
3 || 1 || 0 || 2
4 || 0 || NULL || 1
5 || 1 || 0 || 1
...
我需要找出所有存在的总和以及每个组中所有缺席共享的总和(NULL组也是一个组)。
我无法弄清楚的是,无论该人是否存在,都是通过两列(barcode_presence和manual_presence)的组合来计算出来的:
如果manual_presence = 1 - >本
否则if(manual_presence = NULL且barcode_presence = 1) - >本
其他一切都不存在。
这就是我到目前为止所得到的。
SELECT presence_list.Person_id, presence_list.person_name,
presence_list.barcode_presence, presence_list.manual_presence,
presence_list.group_id, people_data.Share
, sum(people_data.Share)
FROM presence_list
INNER JOIN people_data
ON presence_list.Person_id = people_data.Person_ID
WHERE meeting_id = 1 AND voting_id = 0
GROUP BY presence_list.group_id,
barcode_presence,
manual_presence
ORDER BY presence_list.group_id
;
但很明显,这并没有给我预期的结果。它按group_id,barcode_presence和manual_presence的每种可能组合进行分组,如下所示:
Person_id || barcode_presence || manual_presence || group_id || share || sum(shares)
1 || NULL || 1 || NULL || 100 || 100
2 || 1 || NULL || 1 || 150 || 150
4 || 0 || NULL || 1 || 75 || 75
5 || 1 || 0 || 1 || 45 || 45
3 || 1 || 0 || 2 || 315 || 315
所以我正在寻找一种方法(在这种情况下)连接id为4和5的人,因为他们都不在,他们来自同一个群体,如下所示:
Person_id || barcode_presence || manual_presence || group_id || share || sum(shares)
1 || NULL || 1 || NULL || 100 || 100
2 || 1 || NULL || 1 || 150 || 150
5 || 1 || 0 || 1 || 45 || **120**
3 || 1 || 0 || 2 || 315 || 315
我尝试过使用HAVING
子句,但我没有办法处理像manual_presence = 1 OR (manual_presence is null AND barcode_presence = 1)
这样的复杂表达式
任何想法或建议将不胜感激!先谢谢!
答案 0 :(得分:1)
您可以使用case
为在场和不在场的人群制作小组:
select group_id
, case
when barcode_presence = 1 and manual_presence = 1 then 1
else 0
end
, sum(share)
from presence_list pl
join people_data pd
on pl.person_id = pd.person_id
group by
group_id
, case
when barcode_presence = 1 and manual_presence = 1 then 1
else 0
end
order by
group_id
答案 1 :(得分:1)
如果只能填充两列中的一列,请使用coalesce ...
Group By group_id, Coalesce(barcode_presence, manual_presence)
如果没有,(可以,例如,barcode_presence = 1和presence = 0?),那么你需要决定你想要分组的值的哪些组合,并且只需要按表达式分组...绘制价值组合图表可能会有所帮助......
barcode value
manual Null 0 1
Null GrpA GrpA GrpB
0 GrpC GrpC GrpB
1 GrpB GrpB GrpB
说你想要将那些都是0和其他所有人分组,然后你会写...
Group By group_id, case When isnull(barcode_presence, 0) = 0
And isnull(manual_presence, 0) = 0 Then 0 Else 1 End
答案 2 :(得分:1)
如果我理解正确,我认为生成两列是可行的方法:
select pd.group_id,
SUM(isPresent * pd.shares) as PresentShares,
SUM((1 - isPresent)*pd.shares) as NotPresentShares
from (select pl.*,
(case when manual_presence = 1 or
manual_precence is null and barcode_presence = 1
then 1 else 0
end) as IsPresent
end
from presence_list pl
) pl join
people_data pd
on pl.Person_id = pd.Person_ID
group by pd.group_id
子查询只是应用你的逻辑创建一个标志,当前为1,0表示不存在。方便的是,当以这种方式编码时,“1-IsPresent”为1表示不存在,0表示当前。
然后在聚合中使用此值来聚合共享。您可以将外部查询设为:
select group_id, IsPresent, sum(pd.shares)
from . . .
group by group_id, IsPresent
如果你真的想要在不同的行上使用这些值。