2017-07-17 35 views
1

我有一个代码让我接近我想要的答案。SQL - 两个表格上的条件总和(case when)

现在,代码为不同的估计产生时间间隔的增长,并且它为不同年份返回非空值。然而,我会需要它仅对相关公司在这两个时期都有价值的价值进行求和,而不仅仅是这些时期的价值。

Select m.date_Month 
    ,sum(case when y.date_year = 2016 then n.EBIT end)/sum(case when y.date_year = 2015 then n.EBIT end) - 1 as 'EBIT Growth 2015-2016' 
from EBIT as n 
    inner join date_year as y on y.date_year_id = n.date_year_id 
    inner join date_month as m on m.date_month_id = n.date_month_id 
where n.EBIT<> 0 and m.date_month > '2012-11-30' and m.date_month < '2017-01-31' 
group by m.date_month 
order by m.Date_Month asc; 

我猜想有什么需要添加在总和(情况下......)语法或在where子句中。

简单例子确切地说明我的愿望:

Company_Id Date_Year Date_Month Ebit 
1   2015  2014-12-30 50 
1   2016  2014-12-30 52 
2   2015  2014-12-30 60 
3   2015  2014-12-30 40 
3   2016  2014-12-30 43 

眼下代码看起来在以上表格,并采取:(52 + 43)/(50 + 60 + 40)-1

我它仅需要采取:(52 + 43)/(50 + 40)-1

因此,对于这个具体的Date_Month最终输出理想地:

Date_Month EBIT Growth 2015-2016 
.....   ......  
2014-12-30 0.0556 
.....   ...... 

当前输出(以及代码的期望输出可以在下面看到,但是这些值是错误的,因为它们包含2015年存在但2016年不存在的值(反之亦然)。

date_Month 2014-2015 2015-2016 
2012-12-31 0.025866 NULL 
2013-01-31 0.043509 NULL 
2013-02-28 0.048632 NULL 
2013-03-31 1.120582 NULL 
2013-04-30 0.076691 NULL 
2013-05-31 0.072184 NULL 
2013-06-30 0.078506 NULL 
2013-07-31 0.088014 NULL 
2013-08-31 0.084344 NULL 
2013-09-30 0.088520 NULL 
2013-10-31 0.090181 NULL 
2013-11-30 0.091335 NULL 
2013-12-31 0.094102 0.989785 
2014-01-31 0.094030 0.011348 
2014-02-28 0.096986 0.024370 
2014-03-31 0.096916 0.040109 
2014-04-30 0.098773 0.044166 
2014-05-31 0.099726 0.051751 
2014-06-30 0.099677 0.063474 
2014-07-31 0.099865 0.071188 
2014-08-31 0.101077 0.073944 
2014-09-30 0.101028 0.075055 
2014-10-31 0.090556 0.079508 
2014-11-30 0.083493 0.083621 
2014-12-31 0.070896 0.088688 
2015-01-31 0.072573 0.095857 
2015-02-28 0.077159 0.102403 
2015-03-31 0.082023 0.102581 
2015-04-30 0.076842 0.096223 
2015-05-31 0.088918 0.094773 
2015-06-30 0.084905 0.093353 
2015-07-31 0.075418 0.086845 
2015-08-31 0.061566 0.085217 
2015-09-30 0.051807 0.071888 
2015-10-31 0.060045 0.066542 
2015-11-30 0.072266 0.061107 
2015-12-31 0.050182 0.055806 
2016-01-31 NULL   0.023453 
2016-02-29 NULL   0.029018 
2016-03-31 NULL   0.011684 
2016-04-30 NULL   0.007700 
2016-05-31 NULL   0.012831 
2016-06-30 NULL   0.001756 
2016-07-31 NULL   -0.001628 
2016-08-31 NULL   -0.001095 
2016-09-30 NULL   -0.000649 
2016-10-31 NULL   0.000707 
2016-11-30 NULL   0.015307 
2016-12-31 NULL   0.013374 

由于输入这是几乎产生正是我想要的代码,但它不包括在上面的例子中看到的“空”值:

SELECT 
    m1.date_Month, 
    SUM(n2.EBIT)/
    SUM(n1.EBIT) - 1 AS 'EBIT Growth 2014-2015', 
    SUM(n3.EBIT)/
    SUM(n2.EBIT) - 1 AS 'EBIT Growth 2015-2016' 
FROM EBIT AS n1 
    INNER JOIN date_year AS y1 ON y1.date_year_id = n1.date_year_id 
    INNER JOIN date_month AS m1 ON m1.date_month_id = n1.date_month_id 
INNER JOIN EBIT AS n2 
    INNER JOIN date_year AS y2 ON y2.date_year_id = n2.date_year_id 
    INNER JOIN date_month AS m2 ON m2.date_month_id = n2.date_month_id 
ON n1.Company_Id = n2.company_Id AND m1.date_month = m2.date_month 
INNER JOIN EBIT AS n3 
    INNER JOIN date_year AS y3 ON y3.date_year_id = n3.date_year_id 
    INNER JOIN date_month AS m3 ON m3.date_month_id = n3.date_month_id 
ON n2.Company_Id = n3.company_Id AND m2.date_month = m3.date_month 
WHERE n1.EBIT <> 0 AND n2.EBIT <> 0 and n3.EBIT <> 0 AND y1.date_year = 2014 AND y2.date_year = 2015 and y3.date_year = 2016 
GROUP BY m1.date_month 
ORDER BY m1.Date_Month ASC; 

我使用微软管理工作室。

+0

编辑你的问题,并提供样本数据和预期的结果。 –

+0

我已经稍微编辑了一下,请让我知道如果您需要更多信息来了解我的问题是什么 –

回答

1

考虑重写你的查询,以便你内在加入两个时期(2016年和2015年)使用基于date_monthcompany_id的标准,它应该过滤两个时期之一中缺少company_id的行。当你有每company_idmonth多个记录

SELECT 
    m1.date_Month, 
    SUM(n1.EBIT)/
    SUM(n2.EBIT) - 1 AS 'EBIT Growth 2015-2016' 

FROM EBIT AS n1 
    INNER JOIN date_year AS y1 ON y1.date_year_id = n1.date_year_id 
    INNER JOIN date_month AS m1 ON m1.date_month_id = n1.date_month_id 
INNER JOIN EBIT AS n2 
    INNER JOIN date_year AS y2 ON y2.date_year_id = n2.date_year_id 
    INNER JOIN date_month AS m2 ON m2.date_month_id = n2.date_month_id 
ON n1.Company_Id = n2.company_Id AND m1.date_month = m2.date_month 

WHERE n1.EBIT <> 0 AND n2.EBIT <> 0 AND y1.date_year = 2016 AND y2.date_year = 2015 

GROUP BY m1.date_month 
ORDER BY m1.Date_Month ASC; 

问题就与此解决方案出现。


如果您需要包括NULL值,只需使用LEFT JOIN代替INNER JOIN。在这种情况下,您在任何地方都会获得NULL值,因为指定公司在随后几年中没有匹配的记录,因为x/NULLNULL/x都等于NULL,并且SUM函数忽略NULL值并且仅当所有求和值都为NULL时等于NULL 。因此,即使在接下来的几年中没有相关的值,也会包含结果集中基准年的所有记录。

... 
LEFT JOIN EBIT AS n2 
... 
LEFT JOIN EBIT AS n3 
... 

你也可以有第一个连接内部的和第二个路口左转,如果你需要它,并开始加盟的形式在过去一年有关(2016)。在这种情况下,您只会看到2016-2015年的相关比较,以及2015-2014年的其他比较,其中一些将为空。

事情是这样的:

SELECT 
    m1.date_Month, 
    SUM(n1.EBIT)/
    SUM(n2.EBIT) - 1 AS 'EBIT Growth 2016-2015', 
    SUM(n2.EBIT)/
    SUM(n3.EBIT) - 1 AS 'EBIT Growth 2015-2014' 
FROM EBIT AS n1 
    INNER JOIN date_year AS y1 ON y1.date_year_id = n1.date_year_id 
    INNER JOIN date_month AS m1 ON m1.date_month_id = n1.date_month_id 
INNER JOIN EBIT AS n2 
    INNER JOIN date_year AS y2 ON y2.date_year_id = n2.date_year_id 
    INNER JOIN date_month AS m2 ON m2.date_month_id = n2.date_month_id 
ON n1.Company_Id = n2.company_Id AND m1.date_month = m2.date_month 
LEFT JOIN EBIT AS n3 
    INNER JOIN date_year AS y3 ON y3.date_year_id = n3.date_year_id 
    INNER JOIN date_month AS m3 ON m3.date_month_id = n3.date_month_id 
ON n2.Company_Id = n3.company_Id AND m2.date_month = m3.date_month 
           AND y3.date_year = 2014 
WHERE y1.date_year = 2016 AND y2.date_year = 2015 
GROUP BY m1.date_month 
ORDER BY m1.Date_Month ASC; 
+0

谢谢,这给了我想要的一列,但是当我添加另一列(遵循相同的方法)时,我无法获得我想要的'空'值,因此我只得到一个时间序列,其中所有列都有数据。您是否知道是否有办法让我们对一个时间序列(2015-2016)保持相同的约束,但要使其他时间序列可以具有空值等。(2014-2015年末和2015年 - 2016年开始,因为我们将在2014-2015年初有更多价值,2015-2016年将有更多价值) –

+0

@CedricVongheer检查编辑... –

+0

谢谢,可惜的是代码并没有给我'空'值(也没有改变所有的内部连接到左连接(或只是其中的一部分))。我的系统很可能有点奇怪,因为我知道左连接应该起作用。 但是,如果此查询仍然不检查所使用的数据是否存在于不同的时间段中,我无法使用它。如果有一种方法可以将第一个代码与另一个相同的代码放在一起再进行一次左连接,也许尝试合并一个视图,那么最佳方法是: 谢谢你的帮助! –