2013-10-14 76 views
0

我有一個包含多個值列的表。值可以是整數或NULL。例如:T-SQL將列傳遞給函數作爲參數

LFNR WertA WertB WertC 
1  1  1   2 
2  100  100  200 
3  NULL 1  NULL 
5  1  NULL  1 
6  0  0  0 
40 NULL  1  NULL 

我需要讓每個列的前3個值不爲NULL的平均值。對於單一的專欄中,我得到了所需的平均用這樣的說法:

SELECT AVG(WertA) FROM (SELECT TOP 3 WertA FROM synta_rollmw WHERE WERTA IS NOT NULL ORDER BY lfnr DESC)u 

要在SSRS使用此值,我的想法是使用這樣的功能:

SELECT dbo.func_avg_Wert(WertA), dbo.func_avg_Wert(WertB), ... 

這裏是我的代碼功能:?

CREATE FUNCTION dbo.func_avg_Wert (@col_in varchar(15)) 

RETURNS int 
AS 
BEGIN 

    DECLARE @rollmw int 
    DECLARE @sqlquery VARCHAR(1000) 

    SET @sqlquery = ('SELECT AVG(@col_in) FROM (SELECT TOP 3 @col_in FROM synta_rollMW WHERE @col_in IS NOT NULL ORDER BY lfnr DESC)u') 
    EXEC @sqlquery 
    RETURN @rollmw 

END 
GO 

但是,如果我嘗試使用功能,我得到「列名‘WertA’無效的什麼是錯的或者是有更好的辦法 感謝

+2

你也不能這樣做,因爲'EXEC'在函數中是不允許的,因爲函數不允許有副作用,'EXEC'允許有副作用;請參閱http://stackoverflow.com/q/9607935/130352 –

+1

這通常表示您當前在3列中存儲的內容應該存儲在單個列中(跨越多行),而另一列將保存「 A','B'和'C'--也就是說,您似乎已經結束了想要編寫有關嵌入* names *(元數據)的查詢的數據。 –

+0

對於3個不同的SQL,您可以使用CASE構造... – bummi

回答

0

正如bummi所說,使用CASE可以讓你編寫一個函數。

CREATE FUNCTION dbo.func_avg_Wert (@col_in varchar(15)) 
RETURNS int 
AS 
BEGIN 
    DECLARE @A INT; 
    WITH ColTbl AS 
    (
    SELECT LFNR, 
     CASE @Col_In 
     WHEN 'WertA' THEN WertA 
     WHEN 'WertB' THEN WertB 
     WHEN 'WertC' THEN WertC 
     END AS Wert 
    FROM synta_rollmw 
) 
    SELECT @A = AVG(Wert) 
    FROM 
    (
     SELECT TOP(3) Wert 
     FROM ColTbl 
     WHERE Wert IS NOT NULL 
     ORDER BY lfnr DESC 
)u; 
    RETURN @A; 
END; 

然後,您需要周圍的列名引號時,你怎麼稱呼它:

SELECT dbo.func_avg_Wert('WertA'), dbo.func_avg_Wert('WertB'), dbo.func_avg_Wert('WertC'); 

但是,正如Damien_The_Unbeliever說,想要做這可能意味着你的表是錯誤的設計。

相關問題