计算满足条件的子样本的聚合比率

时间:2014-06-12 22:49:17

标签: sql case aggregate-functions case-when monetdb

我对每个个人ID(loneink)的年度收入(personlopnr),我想计算每个公司ID(peorglopnr)总工资的多少账单是支付给1980年以后出生的工人(出生年份为fodelsear),总计。但是,下面的代码会生成share列,绝大多数情况下为0,其余情况为1。 (要清楚的是,WHERE loneink > 0如下所示的代码只产生1s - 没有那个条件的零回归并且有NULLIF以确保我永远不会除以零。)虽然有许多公司没有年轻工人,显然并非所有其他公司都只是年轻人。

这里有什么问题?这不是产生年轻工资的方法。变量老年工人的收入为零,所以总和只适用于年轻人?或者在理论上这没关系,但我得到CASE WHEN错了?或者SUM / SUM行为不端GROUP BY

有什么更好的方法可以做到这一点?

CREATE VIEW sys.over26_2007 (personlopnr,peorglopnr,loneink,below26_loneink) AS (
SELECT personlopnr,peorglopnr,loneink, CASE WHEN fodelsear < 1981 THEN 0 ELSE loneink END AS below26_loneink
FROM sys.ds_chocker_lev_lisaindivid_2007 WHERE loneink > 0
);
SELECT COUNT(*) FROM over26_2007;

CREATE VIEW sys.share26_2007 (peorglopnr,share26_2007) AS (
SELECT peorglopnr, SUM(below26_loneink)/SUM(loneink)
FROM sys.over26_2007
WHERE loneink > 0
GROUP BY peorglopnr
);

我的实际用例是在MonetDB中,所以我们希望我们只能使用SQL:2003解决方案,不能使用mySQL或Oracle扩展。

1 个答案:

答案 0 :(得分:1)

首先,在创建视图时,需要在case语句中使用0.0。这将确保使用正确的数据类型创建视图中的列(在您的情况下为double):

CREATE VIEW sys.over26_2007 (personlopnr,peorglopnr,loneink,below26_loneink) AS (
SELECT personlopnr,peorglopnr,loneink, 
       CASE WHEN fodelsear < 1981 THEN 0.0 ELSE loneink END AS below26_loneink
FROM sys.ds_chocker_lev_lisaindivid_2007 WHERE loneink > 0.0
);

接下来,在你的另一个视图中,CAST总和也加倍:

CREATE VIEW sys.share26_2007 (peorglopnr,share26_2007) AS (
SELECT peorglopnr, CAST(SUM(below26_loneink) AS double) / CAST(SUM(loneink) AS double)
FROM sys.over26_2007
WHERE loneink > 0
GROUP BY peorglopnr
);