[英]Calculating Yearly Percentage from multiple values from a Single column and in a Single SQL table
一直在尋找有關“根據單個SQL表中單個列中存在的值計算百分比”的幫助。
請讓我給你一點提示(如下):
1.)我正在測試環境中使用SQL2008,需要在SQL2012上部署代碼。
2.)我使用的是SQL游標,因為我需要逐行處理結果並
3.)我使用查詢將這些結果放入新表中:
INSERT INTO tbl_1 (Column_names)
SELECT @Column_names_from_cursor_variables
4.)截至目前,每個ID共有3條記錄,分別是:
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
---------------------------
等等...
我需要為每個id塊計算Percentage_YoY(按年)和Percentage_QoQ(按季度):
QoQ --> ((present_year_value-last_quarter_value)/last_quarter_value)*100
YoY --> ((present_year_value-last_year_value)/last_year_value)*100
但是,以某種方式我無法在SQL游標中找到竅門。 (使用SQL游標不是強制性的,但是我需要按行計算結果,因此我更喜歡使用游標)。
這可能是比您想要的更長的答案,但是我想解決一些有關您的表設置及其重要性的重要事項。 我的解釋會有些倒退,但希望它會很容易理解。
您提供的示例數據可能會有些混亂,因為每個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
這為我們提供了一個類似於Data的表,但帶有一個新字段:
Data
+ -- + --------- + -------- + -- +
| Id | YearValue | SalesQty | RN |
+ -- + --------- + -------- + -- +
| 1 | 052017 | 9876 | 1 | -- PresentYearValue
| 1 | 032017 | 5432 | 2 | -- LastQuarterValue
| 1 | 052016 | 1000 | 3 | -- LastYearValue
| 2 | 052017 | 6483 | 1 | -- repeat
| 2 | 032017 | 2211 | 2 |
| 2 | 052016 | 580 | 3 |
| 3 | 052017 | 11316 | 1 |
| 3 | 032017 | 1216 | 2 |
| 3 | 052016 | 9487 | 3 |
+ -- + --------- + -------- + -- +
注意RN與(Present,Last)(Quarter,Year)Value之間的對應關系。 我們可以利用這種對應關系將行“透視”為列。
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
從子句前添加你想要的任何其他領域,你到條款。 希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.