Sql server T-SQL将列作为参数传递给函数

Sql server T-SQL将列作为参数传递给函数,sql-server,Sql Server,我有一个具有多个值列的表。值可以是整数或NULL。例如: 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。例如:

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个值的平均值。对于单个列,我通过以下语句获得所需的平均值:

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
但是如果我尝试使用这个函数,我得到的“Column name‘WertA’无效。这是怎么回事,或者有更好的方法吗?
谢谢

正如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_所说,想要这样做可能意味着您的表设计错误。

您也无法这样做,因为函数中不允许使用“EXEC”,因为函数不允许有副作用,“EXEC”允许有副作用;这通常是一个迹象,表明您当前存储在3列中的内容应该在n一个列(跨多行)和一个附加列将包含
a
B
C
——也就是说,您似乎最终得到了要在名称(元数据)中嵌入查询的数据。您可以为3个不同的SQL使用CASE构造