我正在尝试创建函数来计算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;
答案 0 :(得分: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)
)
...
答案 1 :(得分: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;
答案 2 :(得分: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