我需要参数化我的查询,以便对于每个期间(1-12),它产生期间的余额以及每个期间直到所选期间(YTD)的所有余额的总和。我的表看起来像这样(Am字段是该年度每个时期的金额)
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,但我宁愿使用一些可以做我需要做的逻辑。
答案 0 :(得分: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 :(得分: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返回多行直到指定的时间段(即1-4期)
你的问题不是100%明确你想要的。随便挑选。
答案 2 :(得分: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
答案 3 :(得分: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 ...