2

所以我有两张桌子。一种是人们拥有的股份数量:

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 --> 存在

else if (manual_presence = NULL andbarcode_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)

任何想法或建议将不胜感激!预先感谢!

4

3 回答 3

2

如果只能填充两列中的一列,请使用合并...

 Group By group_id, Coalesce(barcode_presence, manual_presence)

如果不是,(可以说,barcode_presence = 1 和存在 = 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
于 2013-02-12T14:20:33.613 回答
1

您可以使用 acase为在场和不在场的人创建一个组:

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
于 2013-02-12T14:20:20.023 回答
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

如果您真的想要单独行上的值。

于 2013-02-12T14:39:14.750 回答