Я думаю, что лучший способ сделать это - обернуть вычисление процентного кода в пользовательскую функцию (udf), которая возвращает таблицу.Передайте переменную типа таблицы в udf, выполните вычисления в udf и вызовите udf, чтобы получить набор результатов в виде строк данных таблицы.Однако для передачи таблицы в udf необходимо создать тип таблицы, определяемый пользователем.
Вот примеры кодов:
/ * Create User Defined Table Type */
CREATE TYPE x2_SrcCntTableType AS TABLE (
id int identity(1,1)
,Src varchar(100)
, Yr1Cnt money
, Yr1Per varchar(20)
, Yr2Cnt money
, Yr2Per varchar(20))
GO
/* Create User Defined Table-Valued Function */
CREATE FUNCTION x2_getSrcCntPercentage
(
@srcCntOrig x2_SrcCntTableType READONLY -- this table should always readonly
)
RETURNS
@SrcCnt TABLE
(
-- Add the column definitions for the TABLE variable here
id int identity(1,1)
, Src varchar(100)
, Yr1Cnt money
, Yr1Per varchar(20)
, Yr2Cnt money
, Yr2Per varchar(20)
)
AS
BEGIN
-- Fill the table variable with the rows for your result set
-- copy data from @srcCntOrig to @SrcCnt table
-- because srcCntOrig is readonly, so do the udates on table SrcCnt
insert into @SrcCnt(Src, Yr1Cnt,Yr2Cnt)
SELECT Src, Yr1Cnt,Yr2Cnt FROM @srcCntOrig
insert into @SrcCnt(Src, Yr1Cnt,Yr2Cnt)
select 'Total', sum(Yr1Cnt), sum(Yr2Cnt) from @SrcCnt
declare @Yr1Tot int, @Yr2Tot int
select @Yr1Tot = Yr1Cnt, @Yr2Tot = Yr2Cnt from @SrcCnt where Src = 'Total'
update @SrcCnt set Yr1Per = (Yr1Cnt * 100)/@Yr1Tot
update @SrcCnt set Yr2Per = (Yr2Cnt * 100)/@Yr2Tot
update @SrcCnt set Yr1Per = case when Yr1Per = '0' then null else Yr1Per + '%' end
update @SrcCnt set Yr2Per = case when Yr2Per = '0' then null else Yr2Per + '%' end
-- select * from #SrcCnt order by id
RETURN
END
GO
И затем вы можете вызвать udf из запроса / хранимой процедуры:
declare @SrcCnt x2_SrcCntTableType
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt) VALUES ('0 - 5 Years',143,43)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt) VALUES ('6 - 10 Years',28,17)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt) VALUES ('11 - 15 Years',9,5)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt) VALUES ('16 - 20 Years',7,2)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt) VALUES ('21 - 30 Years',11,3)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt) VALUES ('> 30 Years',91,55)
SELECT * from dbo.x2_getSrcCntPercentage(@SrcCnt)
Результат:
id Src Yr1Cnt Yr1Per Yr2Cnt Yr2Per
---------------------------------------------------
1 0 - 5 Years 143,00 49.48% 43,00 34.40%
2 6 - 10 Years 28,00 9.69% 17,00 13.60%
3 11 - 15 Years 9,00 3.11% 5,00 4.00%
4 16 - 20 Years 7,00 2.42% 2,00 1.60%
5 21 - 30 Years 11,00 3.81% 3,00 2.40%
6 > 30 Years 91,00 31.49% 55,00 44.00%
7 Total 289,00 100.00% 125,00 100.00%
(обновлено) ОК.Есть еще один вариант без использования UDF.Однако вам необходимо иметь общее количество Yr1Cnt и Yr2Cnt, прежде чем делать вставки в таблицу @SrcCnt.Хитрость в том, чтобы использовать компьютерную колонку.
Вот частичный код вашей хранимой процедуры:
declare @SrcCnt TABLE
(
-- Add the column definitions for the TABLE variable here
id int identity(1,1)
, Src varchar(100)
, Yr1Cnt money
, Yr1Per AS Cast(Cast((Yr1Cnt/TotYr1Cnt)*100 as decimal(18,2)) as varchar(10)) + ' %' -- COMPUTED COLUMN
, Yr2Cnt money
, Yr2Per AS Cast(Cast((Yr2Cnt/TotYr2Cnt)*100 as decimal(18,2)) as varchar(10)) + ' %' -- COMPUTED COLUMN
, TotYr1Cnt money
, TotYr2Cnt money
)
declare @TotYr1Cnt money = 289 -- maybe calculated elsewhere but prior to inserting data to @SrcCnt
declare @TotYr2Cnt money = 125
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt,TotYr1Cnt,TotYr2Cnt) VALUES ('0 - 5 Years',143,43,@TotYr1Cnt,@TotYr2Cnt)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt,TotYr1Cnt,TotYr2Cnt) VALUES ('6 - 10 Years',28,17,@TotYr1Cnt,@TotYr2Cnt)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt,TotYr1Cnt,TotYr2Cnt) VALUES ('11 - 15 Years',9,5,@TotYr1Cnt,@TotYr2Cnt)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt,TotYr1Cnt,TotYr2Cnt) VALUES ('16 - 20 Years',7,2,@TotYr1Cnt,@TotYr2Cnt)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt,TotYr1Cnt,TotYr2Cnt) VALUES ('21 - 30 Years',11,3,@TotYr1Cnt,@TotYr2Cnt)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt,TotYr1Cnt,TotYr2Cnt) VALUES ('> 30 Years',91,55,@TotYr1Cnt,@TotYr2Cnt)
INSERT INTO @SrcCnt(Src,Yr1Cnt,Yr2Cnt,TotYr1Cnt,TotYr2Cnt) VALUES ('Total',@TotYr1Cnt,@TotYr2Cnt,@TotYr1Cnt,@TotYr2Cnt)
SELECT * FROM @SrcCnt