2014-10-07 45 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 ...