2

我正在尝试创建函数来计算 3 个值的中位数,但几乎没有错误-“函数内的 Stmt 无法将数据返回给客户端”

CREATE FUNCTION median(@value1 float,@value2 float,@value3 float)
RETURNS float
AS
BEGIN
    DECLARE @ret float;
    DECLARE @CNT int = 3;

    select cast(avg(tb1.val*1.0) as float) as @ret
    from 
       (select 
          val, ROW_NUMBER() over (order by val) as rid 
        from 
            (select @value1 val
         union 
             select @value2 val
         union
             select @value3 val) TB1
        where tb1.rid in ((@cnt + 1) / 2, (@cnt + 2) / 2)

    return @ret;
end;
4

3 回答 3

4

你的语法是错误的。您选择的是函数中间的结果集,而不是将值分配给局部变量,因此会出现错误。试试这个:

...
set @ret = (select cast(avg(tb1.val*1.0) as float) 
    from (select val, ROW_NUMBER() over (order by val) as rid from 
            (select @value1 val
            union 
            select @value2 val
            union
            select @value3 val) TB1
    where tb1.rid in ((@cnt+1)/2,(@cnt+2)/2)
    )
...
于 2013-07-22T18:41:49.597 回答
0
CREATE FUNCTION medianx(@value1 float,@value2 float,@value3 float)
RETURNS numeric(10,2)
AS
    BEGIN
        DECLARE @ret float;
        DECLARE @CNT int = 3;
        select @ret=cast(avg(tb1.val*1.0) as numeric(10,2)) 
            from (select val, ROW_NUMBER() over (order by val) as rid from 
                (select @value1 val
                union 
                select @value2 val
                union
                select @value3 val) TB1) TB1
        where tb1.rid in ((@cnt+1)/2,(@cnt+2)/2)



    RETURN @ret
    end;
于 2013-07-22T18:48:42.810 回答
0

在这种情况下,当一个或多个输入参数可能具有NULL值时:

create function median(@v1 float, @v2 float, @v3 float)
returns float
as
begin
    declare @median float;

    ;with D(V, N) as (
        select V, row_number() over (order by V)
        from (values (@v1), (@v2), (@v3)) T(V)
        where V is not NULL)
    ,C(Cnt) as (select count(1) from D)
    select @median = (
        select avg(V) as Median
        from C, D
        where C.Cnt % 2 = 1 and N = C.Cnt/2 + 1
            or C.Cnt % 2 = 0 and N in (C.Cnt/2, C.Cnt/2 + 1))

    return @median;
end

上面的函数可以写成更通用的形式,允许将三个以上的值作为表参数传递:

create type FloatData as table (Value float)
GO
create function median(@data as FloatData readonly)
returns float
as
begin
    declare @median float;

    ;with D(V, N) as (
        select Value, row_number() over (order by Value)
        from @data
        where Value is not NULL)
    ,C(Cnt) as (select count(1) from D)
    select @median = (
        select avg(V) as Median
        from C, D
        where C.Cnt % 2 = 1 and N = C.Cnt/2 + 1
            or C.Cnt % 2 = 0 and N in (C.Cnt/2, C.Cnt/2 + 1))

    return @median;
end
GO
于 2013-07-22T20:59:46.490 回答