2017-07-17 108 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

謝謝,可惜的是代碼並沒有給我'空'值(也沒有改變所有的內部連接到左連接(或只是其中的一部分))。我的系統很可能有點奇怪,因爲我知道左連接應該起作用。 但是,如果此查詢仍然不檢查所使用的數據是否存在於不同的時間段中,我無法使用它。如果有一種方法可以將第一個代碼與另一個相同的代碼放在一起再進行一次左連接,也許嘗試合併一個視圖,那麼最佳方法是: 謝謝你的幫助! –