2014-10-07 46 views
0

計算我需要參數化我的查詢,以便在每個時間段(1-12)中產生期間的餘額以及每個期間的所有餘額的總和,直到所選期間(YTD)。我的表看起來像這樣(上午場是該年度各會計期間的數據)在SQL中的select語句中循環以根據參數

COMPANY|ACCOUNT|SUB_ACCOUNT|FISCAL_YEAR|DB_AMOUNT_01|DB_AMOUNT_02|DB_AMOUNT_03|DB_AMOUNT_04|DB_AMOUNT_05|DB_AMOUNT_06|DB_AMOUNT_07|DB_AMOUNT_08|DB_AMOUNT_09|DB_AMOUNT_10|DB_AMOUNT_11|DB_AMOUNT_12| 
1|10000|1001|2014|176511106.65|200917064.20|243331258.93|189877339.46|208405555.85|316912751.86|413405072.40|0.00|0.00|0.00|0.00|0.00 
1|10020|1001|2014|7162276.27|10429413.89|12552480.96|11144442.08|8627365.16|13453884.90|12607065.52|0.00|0.00|0.00|0.00|0.00 
1|10040|1001|2014|8942858.81|11088886.79|11827043.98|12549230.43|12052482.22|12511277.79|9963556.61|0.00|0.00|0.00|0.00|0.00 

我需要做的是顯示當用戶選擇週期各個時期但增加了對所有與前幾個月的數據初始餘額。因此,如果用戶選擇時段3,它應該看起來像

COMPANY|ACCOUNT|SUB_ACCOUNT|FISCAL_YEAR|DB_AMOUNT_03|YTD_AMOUNT 
1|10000|1001|2014|243331258.93|176511106.65+200917064.20+243331258.93 

但對於第4期這將是

COMPANY|ACCOUNT|SUB_ACCOUNT|FISCAL_YEAR|DB_AMOUNT_04|YTD_AMOUNT 
1|10000|1001|2014|189877339.46|176511106.65+200917064.20+243331258.93+189877339.46 

等等

但我怎麼能做出另外的YTD_AMOUNT字段的時間是由用戶選擇的? 我可以編寫12個不同的語句,併爲每個時期做一個IF/THEN,但我寧願使用某種邏輯來完成我需要做的事情。

回答

1

如果我正確理解你的問題,這聽起來像你試圖unpivot你的表。答案可以根據您的RDBMS而有所不同,但這是一個通用的解決方案,應該可以工作。

您首先需要創建一個數字/句號表。一種選擇是使用UNION ALL的子查詢來實現此目的。然後,您可以使用與CASE的聚合來獲得您想要的結果。

下面是使用6個週期的精簡版(添加其他語句爲12個週期):

select company, account, sub_account, fiscal_year, 
    max(
    case 
     when amt = 1 then db_amount_01 
     when amt = 2 then db_amount_02 
     when amt = 3 then db_amount_03 
     when amt = 4 then db_amount_04 
     when amt = 5 then db_amount_05 
     when amt = 6 then db_amount_06 
    end 
    ) amt, 
    sum(
    case 
     when amt = 1 then db_amount_01 
     when amt = 2 then db_amount_01+db_amount_02 
     when amt = 3 then db_amount_01+db_amount_02+db_amount_03 
     when amt = 4 then db_amount_01+db_amount_02+db_amount_03+db_amount_04 
     when amt = 5 then db_amount_01+db_amount_02+db_amount_03+db_amount_04+db_amount_05 
     when amt = 6 then db_amount_01+db_amount_02+db_amount_03+db_amount_04+db_amount_05+db_amount_06 
    end 
    ) overallamt 
from YourTable t , 
    (select 1 amt union all select 2 union all select 3 union all 
    select 4 union all select 5 union all select 6) t2 
group by company, account, sub_account, fiscal_year, amt 
1

對於非常大的GL表,其中交叉連接到一個12週期日曆表可能會令人望而卻步,另一種解決方案是這樣的:

declare @Period INT 
set @Period = 4 

select company, account, sub_account, fiscal_year, 
case @Period 
when 1 then db_amount_01 
when 2 then db_amount_02 
when 3 then db_amount_03 
when 4 then db_amount_04 
.... 
end amt, 
case @Period 
when 1 then db_amount_01 
when 2 then db_amount_01 + db_amount_02 
when 3 then db_amount_01 + db_amount_02 + db_amount_03 
when 4 then db_amount_01 + db_amount_02 + db_amount_03 + db_amount_04 
.... 
end balance 
from YourTable t 

這些表格通常還有一個期初期餘額欄 - 如果需要,您必須包括這些表。

這之間的區別和@sgeddes答案是返回每個帳戶/年一排(即剛剛期間4),而@sgeddes返回多行至specfied期間(即,週期1-4)

從你的問題中不能100%清楚你想要哪一個。拿你的選擇。

0

如果我正確理解你的問題,我認爲你可以使用動態SQL。我寫了以下針對Sql Server。 @periodNum是您要查找的期數的參數;在這個例子中,我要求前6個時期。

DECLARE @periodNum INT; 
SET @periodNum = 6; 

DECLARE @firstPeriodColNum INT; 
DECLARE @periodCol NVARCHAR(50), @columnNm NVARCHAR(50), @prevColumnNm NVARCHAR(50); 
DECLARE @queryTxt NVARCHAR(1000); 
DECLARE @Columns TABLE (column_name NVARCHAR(50)); 

--Retrieve ordinal position for first period column 
SELECT @firstPeriodColNum = ORDINAL_POSITION 
        FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE COLUMN_NAME = 'DB_AMOUNT_01'; 

--Retrieve column name for period of interest 
SELECT @periodCol = COLUMN_NAME 
        FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_NAME = 'YourTableName' --just table name, no schema 
         AND ORDINAL_POSITION = (@periodNum + @firstPeriodColNum - 1); 

--Retrieve column names for all periods up to and including the period of interest 
INSERT INTO @Columns 
SELECT COLUMN_NAME 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'YourTableName' 
    AND ORDINAL_POSITION >= @firstPeriodColNum 
     AND ORDINAL_POSITION < (@periodNum + @firstPeriodColNum); 

--declare cursor over table variable of period-column names 
--run through cursor and dynamically add the column names to the query string @queryTxt 
DECLARE COL_CURSOR CURSOR FOR 
SELECT * FROM @Columns; 
OPEN COL_CURSOR; 

FETCH NEXT FROM COL_CURSOR INTO @columnNm; 
SET @queryTxt = 'SELECT COMPANY, ACCOUNT, SUB_ACCOUNT, FISCAL_YEAR, ' 
       + @periodCol + ', (' + @columnNm; 
SET @prevColumnNm = @columnNm; 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    FETCH NEXT FROM COL_CURSOR INTO @columnNm; 
    IF @prevColumnNm <> @columnNm 
    BEGIN 
     SET @queryTxt = @queryTxt + ' + ' + @columnNm; 
     SET @prevColumnNm = @columnNm; 
    END 
    ELSE CONTINUE 
END 
CLOSE COL_CURSOR; 
DEALLOCATE COL_CURSOR; 

SET @queryTxt = @queryTxt + ') AS YTD FROM YourTableName'; 

EXEC (@queryTxt); --Executes the query 
0

所以我用了很多的輸入(謝謝!),並做了這樣的結尾:

SELECT distinct 
    d.ACCOUNT_DESC, 
    a.COMPANY, 
    a.ACCOUNT, 
    a.SUB_ACCOUNT, 
    a.FISCAL_YEAR, 
    CASE @period 
    WHEN 1 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01 
    WHEN 2 THEN a.DB_AMOUNT_02+a.CR_AMOUNT_02 
    WHEN 3 THEN a.DB_AMOUNT_03+a.CR_AMOUNT_03 
    WHEN 4 THEN a.DB_AMOUNT_04+a.CR_AMOUNT_04 
    WHEN 5 THEN a.DB_AMOUNT_05+a.CR_AMOUNT_05 
    WHEN 6 THEN a.DB_AMOUNT_06+a.CR_AMOUNT_06 
    WHEN 7 THEN a.DB_AMOUNT_07+a.CR_AMOUNT_07 
    WHEN 8 THEN a.DB_AMOUNT_08+a.CR_AMOUNT_08 
    WHEN 9 THEN a.DB_AMOUNT_09+a.CR_AMOUNT_09 
    WHEN 10 THEN a.DB_AMOUNT_10+a.CR_AMOUNT_10 
    WHEN 11 THEN a.DB_AMOUNT_11+a.CR_AMOUNT_11 
    WHEN 12 THEN a.DB_AMOUNT_12+a.CR_AMOUNT_12 
    WHEN 13 THEN a.DB_AMOUNT_13+a.CR_AMOUNT_13 

    END CHANGE , 
    CASE @period 
    WHEN 2 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01 
    WHEN 3 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02 
    WHEN 4 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03 
    WHEN 5 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04 
    WHEN 6 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04+a.DB_AMOUNT_05+a.CR_AMOUNT_05 
    WHEN 7 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04+a.DB_AMOUNT_05+a.CR_AMOUNT_05+a.DB_AMOUNT_06+a.CR_AMOUNT_06 
    WHEN 8 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04+a.DB_AMOUNT_05+a.CR_AMOUNT_05+a.DB_AMOUNT_06+a.CR_AMOUNT_06+a.DB_AMOUNT_07+a.CR_AMOUNT_07 
    WHEN 9 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04+a.DB_AMOUNT_05+a.CR_AMOUNT_05+a.DB_AMOUNT_06+a.CR_AMOUNT_06+a.DB_AMOUNT_07+a.CR_AMOUNT_07+a.DB_AMOUNT_08+a.CR_AMOUNT_08 
    WHEN 10 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04+a.DB_AMOUNT_05+a.CR_AMOUNT_05+a.DB_AMOUNT_06+a.CR_AMOUNT_06+a.DB_AMOUNT_07+a.CR_AMOUNT_07+a.DB_AMOUNT_08+a.CR_AMOUNT_08+a.DB_AMOUNT_09+a.CR_AMOUNT_09 
    WHEN 11 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04+a.DB_AMOUNT_05+a.CR_AMOUNT_05+a.DB_AMOUNT_06+a.CR_AMOUNT_06+a.DB_AMOUNT_07+a.CR_AMOUNT_07+a.DB_AMOUNT_08+a.CR_AMOUNT_08+a.DB_AMOUNT_09+a.CR_AMOUNT_09+a.DB_AMOUNT_10+a.CR_AMOUNT_10 
    WHEN 12 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04+a.DB_AMOUNT_05+a.CR_AMOUNT_05+a.DB_AMOUNT_06+a.CR_AMOUNT_06+a.DB_AMOUNT_07+a.CR_AMOUNT_07+a.DB_AMOUNT_08+a.CR_AMOUNT_08+a.DB_AMOUNT_09+a.CR_AMOUNT_09+a.DB_AMOUNT_10+a.CR_AMOUNT_10+a.DB_AMOUNT_11+a.CR_AMOUNT_11 
    WHEN 13 THEN a.DB_AMOUNT_01+a.CR_AMOUNT_01+a.DB_AMOUNT_02+a.CR_AMOUNT_02+a.DB_AMOUNT_03+a.CR_AMOUNT_03+a.DB_AMOUNT_04+a.CR_AMOUNT_04+a.DB_AMOUNT_05+a.CR_AMOUNT_05+a.DB_AMOUNT_06+a.CR_AMOUNT_06+a.DB_AMOUNT_07+a.CR_AMOUNT_07+a.DB_AMOUNT_08+a.CR_AMOUNT_08+a.DB_AMOUNT_09+a.CR_AMOUNT_09+a.DB_AMOUNT_10+a.CR_AMOUNT_10+a.DB_AMOUNT_11+a.CR_AMOUNT_11+a.DB_AMOUNT_12+a.CR_AMOUNT_12 
    END +a.DB_BEG_BAL + a.CR_BEG_BAL LAST_MONTH, 
    a.DB_BEG_BAL + a.CR_BEG_BAL AS BEGINBAL, 

    CASE @period 
    WHEN 1 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01 
    WHEN 2 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02 
    WHEN 3 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03 
    WHEN 4 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04 
    WHEN 5 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05 
    WHEN 6 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05+z.DB_AMOUNT_06+z.CR_AMOUNT_06 
    WHEN 7 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05+z.DB_AMOUNT_06+z.CR_AMOUNT_06+z.DB_AMOUNT_07+z.CR_AMOUNT_07 
    WHEN 8 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05+z.DB_AMOUNT_06+z.CR_AMOUNT_06+z.DB_AMOUNT_07+z.CR_AMOUNT_07+z.DB_AMOUNT_08+z.CR_AMOUNT_08 
    WHEN 9 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05+z.DB_AMOUNT_06+z.CR_AMOUNT_06+z.DB_AMOUNT_07+z.CR_AMOUNT_07+z.DB_AMOUNT_08+z.CR_AMOUNT_08+z.DB_AMOUNT_09+z.CR_AMOUNT_09 
    WHEN 10 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05+z.DB_AMOUNT_06+z.CR_AMOUNT_06+z.DB_AMOUNT_07+z.CR_AMOUNT_07+z.DB_AMOUNT_08+z.CR_AMOUNT_08+z.DB_AMOUNT_09+z.CR_AMOUNT_09+z.DB_AMOUNT_10+z.CR_AMOUNT_10 
    WHEN 11 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05+z.DB_AMOUNT_06+z.CR_AMOUNT_06+z.DB_AMOUNT_07+z.CR_AMOUNT_07+z.DB_AMOUNT_08+z.CR_AMOUNT_08+z.DB_AMOUNT_09+z.CR_AMOUNT_09+z.DB_AMOUNT_10+z.CR_AMOUNT_10+z.DB_AMOUNT_11+z.CR_AMOUNT_11 
    WHEN 12 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05+z.DB_AMOUNT_06+z.CR_AMOUNT_06+z.DB_AMOUNT_07+z.CR_AMOUNT_07+z.DB_AMOUNT_08+z.CR_AMOUNT_08+z.DB_AMOUNT_09+z.CR_AMOUNT_09+z.DB_AMOUNT_10+z.CR_AMOUNT_10+z.DB_AMOUNT_11+z.CR_AMOUNT_11+z.DB_AMOUNT_12+z.CR_AMOUNT_12 
    WHEN 13 THEN z.DB_AMOUNT_01+z.CR_AMOUNT_01+z.DB_AMOUNT_02+z.CR_AMOUNT_02+z.DB_AMOUNT_03+z.CR_AMOUNT_03+z.DB_AMOUNT_04+z.CR_AMOUNT_04+z.DB_AMOUNT_05+z.CR_AMOUNT_05+z.DB_AMOUNT_06+z.CR_AMOUNT_06+z.DB_AMOUNT_07+z.CR_AMOUNT_07+z.DB_AMOUNT_08+z.CR_AMOUNT_08+z.DB_AMOUNT_09+z.CR_AMOUNT_09+z.DB_AMOUNT_10+z.CR_AMOUNT_10+z.DB_AMOUNT_11+z.CR_AMOUNT_11+z.DB_AMOUNT_12+z.CR_AMOUNT_12+z.DB_AMOUNT_13+z.CR_AMOUNT_13 
    END PYP 
    from GLCONSOL a , GLCONSOL z, GLCHARTDTL d, GLMASTER m 
    where ...