2017-05-30 65 views
0

一直在尋找一些關於「根據單個SQL表中單列中的值計算百分比」的幫助。計算單列和單個SQL表中多個值的年度百分比

請允許我給你一點點擡頭(如下):

1)我在我的測試環境是在SQL2008工作,並需要部署代碼是SQL2012。

2)我使用的是SQL遊標,因爲我需要的結果行由行處理和

3)這些結果我現在用的查詢將進入一個新的表:

INSERT INTO tbl_1 (Column_names) 
SELECT @Column_names_from_cursor_variables 

4)有(截至目前)正好3記錄每個ID爲:

present_year_value (say,MAY2017), 
last_quarter_value (say,MAR2017) 
last_year_value (say,MAY2016) 

如下:

id  yearValue salesQty 
----------------------------- 
1  052017  9876  
1  032017  5432  
1  052016  1000  
---------------------------  
2  052017  9876  
2  032017  5432  
2  052016  1000  
---------------------------  
3  052017  9876  
3  032017  5432  
3  052016  1000  
--------------------------- 

等等...

我需要計算Percentage_YoY(年同比),以及 Percentage_QoQ(較上一季度)爲ID的每個塊爲:

QoQ --> ((present_year_value-last_quarter_value)/last_quarter_value)*100 

YoY --> ((present_year_value-last_year_value)/last_year_value)*100 

但是,不知何故,我無法獲得SQL遊標中的技巧。 (使用SQL遊標不是強制性的,但我需要逐行計算結果,因此我更願意使用Cursor)。

+0

此表中的id是什麼? (如產品編號或相關的另一張表?任何唯一的ID) –

+0

你好Samanvitha,該ID是在表的主鍵,它已(完全一致)3記錄每個 –

+0

問題是什麼?你得到的結果是不正確的? – nscheaffer

回答

0

這可能是比您想要的更長的答案,但我想解決幾個關於您的表格設置以及它們爲什麼重要的重要內容。我的解釋會稍微有些落後,但希望它會很容易遵循。

你給可以是一個有點混亂,因爲它是每個ID都是一樣的,所以我要改變他們有點像這樣的例子數據:

Data 
+ -- + --------- + -------- + 
| Id | YearValue | SalesQty | 
+ -- + --------- + -------- + 
| 1 | 052017 | 9876  | 
| 1 | 032017 | 5432  | 
| 1 | 052016 | 1000  | 
| 2 | 052017 | 6483  | 
| 2 | 032017 | 2211  | 
| 2 | 052016 | 580  | 
| 3 | 052017 | 11316 | 
| 3 | 032017 | 1216  | 
| 3 | 052016 | 9487  | 
+ -- + --------- + -------- + 

開始,如果您的表看起來像這樣,而不是答案應該是顯而易見:

Values 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 
| Id | CurrentDate | PresentYearValue | LastQuarterValue | LastYearValue | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 
| 1 | 052017  | 9876    | 5432    | 1000   | 
| 2 | 052017  | 6483    | 2211    | 580   | 
| 3 | 052017  | 11316   | 1216    | 9487   | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 

然後,假設你的數據類型爲SalesQty字段不是一個小數,您可以使用下面的查詢:

select Id 
     , cast((PresentYearValue - LastQuarterValue) as float)/(LastQuarterValue) * 100 as QoQ 
     , cast((PresentYearValue - LastYearValue) as float)/(LastYearValue) * 100 as YoY 
    from Values 

,你會得到以下結果:

Results 
+ -- + ------ + ------- + 
| Id | QoQ | YoY  | 
+ -- + ------ + ------- + 
| 1 | 81.81 | 887.6 | 
| 2 | 193.22 | 1017.76 | 
| 3 | 830.59 | 19.28 | 
+ -- + ------ + ------- + 

非常簡單明瞭。

但是...

它可能並不總是做出這樣的改變你的數據庫是可行的。例如,數據可能不僅僅用於這一個單一的問題,而且以您的格式存儲它可能是最好的整體。在這種情況下,這是一個演示如何轉換數據以獲得您想要的結果。

爲了使我們的數據表看起來像我們的值表,我們需要一個明確的在Id的內部排序。在這種情況下,我們可以在YearValue字段上訂購,但如果它們是實際日期而不是字符串,則只能訂購。考慮下面的查詢:

select *, ROW_NUMBER() over (partition by Id order by YearValue desc) as RN 
    from Values 

這給了我們類似的數據,但一個新的字段的表:

​​

通知RN和(目前,最後)(季,年)值之間的對應關係。我們可以利用這種對應關係將這些行「轉」爲列。

select a.Id 
     , case RN when 1 then a.YearValue end as CurrentDate 
     , case RN when 1 then a.SalesQty end as PresentYearValue 
     , case RN when 2 then a.SalesQty end as LastQuarterValue 
     , case RN when 3 then a.SalesQty end as LastYearValue 
     , a.RN as RN 
    from (
     select *, ROW_NUMBER() over (partition by id order by SalesQty desc) as RN 
      from #Values 
    ) a 

這讓我們像

+ -- + ----------- + ---------------- + ---------------- + ------------- + -- + 
| Id | CurrentDate | PresentYearValue | LastQuarterValue | LastYearValue | RN | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + -- + 
| 1 | 2017-05-01 | 9876    | NULL    | NULL   | 1 | 
| 1 | 2017-05-01 | NULL    | 5432    | NULL   | 2 | 
| 1 | 2017-05-01 | NULL    | NULL    | 1000   | 3 | 
| 2 | 2017-05-01 | 6483    | NULL    | NULL   | 1 | 
| 2 | 2017-05-01 | NULL    | 2211    | NULL   | 2 | 
| 2 | 2017-05-01 | NULL    | NULL    | 580   | 3 | 
| 3 | 2017-05-01 | 11316   | NULL    | NULL   | 1 | 
| 3 | 2017-05-01 | NULL    | 9487    | NULL   | 2 | 
| 3 | 2017-05-01 | NULL    | NULL    | 1216   | 3 | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + -- + 

表一快速分組,我們可以收起該表格。

select a.Id 
     , max(case RN when 1 then a.YearValue end) as CurrentDate 
     , max(case RN when 1 then a.SalesQty end) as PresentYearValue 
     , max(case RN when 2 then a.SalesQty end) as LastQuarterValue 
     , max(case RN when 3 then a.SalesQty end) as LastYearValue 
    from (
     select *, ROW_NUMBER() over (partition by id order by YearValue desc) as RN 
      from Data 
    ) a 
    group by a.Id 

,這爲我們提供了準確的值表:

Values 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 
| Id | CurrentDate | PresentYearValue | LastQuarterValue | LastYearValue | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 
| 1 | 052017  | 9876    | 5432    | 1000   | 
| 2 | 052017  | 6483    | 2211    | 580   | 
| 3 | 052017  | 11316   | 1216    | 9487   | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 

最後,掖最後查詢到的CTE,並與第一查詢結合起來,以獲得您想要的值:

; with 
    Values as (
     select a.Id 
       , max(case RN when 1 then a.YearValue end) as CurrentDate 
       , max(case RN when 1 then a.SalesQty end) as PresentYearValue 
       , max(case RN when 2 then a.SalesQty end) as LastQuarterValue 
       , max(case RN when 3 then a.SalesQty end) as LastYearValue 
      from (
       select *, ROW_NUMBER() over (partition by id order by YearValue desc) as RN 
        from Data 
      ) a 
      group by a.Id 
    ) 
select Id 
     , cast((PresentYearValue - LastQuarterValue) as float)/(LastQuarterValue) * 100 as QoQ 
     , cast((PresentYearValue - LastYearValue) as float)/(LastYearValue) * 100 as YoY 
    from Values 

在from子句之前,將所需的任何其他字段和添加到子句中。希望這可以幫助!

+0

Ohh Gosh @KindaTechy,我已經閱讀過這篇教程的種類回覆,但從外觀上看,我認爲這可以工作(儘管如此,我仍然需要嘗試這一切)。請給我一些時間來反思這個代碼,並嘗試做一些小的改動。一定會回到你身邊。再一次,謝謝!提前#allCreditToYou_KindaTechy –

+0

@ E.Hunt我希望這對你的作品。讓我知道,如果不是這樣,也許我們可以找出原因:) – KindaTechy

+0

是它的工作原理,我能與你的邏輯的幫助下對其進行修改和一個大感謝你指導我。從你的這份辛勤工作中學到很多東西。 –