Tôi sẽ không sử dụng hàm vô hướng cho loại hoạt động này. Kết quả là bạn có hiệu suất kém vì trình tối ưu hóa truy vấn cần chạy nó row-by-row
mà không có bất kỳ tối ưu hóa nào. Thông tin thêm: SQL Server Functions: The Basics
.
Thứ hai với float / decimal và LOG/EXP
bạn sẽ nhận được lỗi ước lượng.
Thứ ba để chuyển dữ liệu cho chức năng, bạn có thể sử dụng XML
như:
CREATE FUNCTION dbo.udf_Mul(@value xml)
RETURNS FLOAT
AS
BEGIN
DECLARE @mul_value FLOAT;
DECLARE @values AS TABLE ([value] float);
INSERT INTO @values([value])
SELECT [value] = t.c.value('(value)[1]', 'float')
FROM @value.nodes('//row') AS t(c);
SELECT @mul_value=CASE
WHEN MinVal = 0 THEN 0
WHEN Neg % 2 = 1 THEN -1 * Exp(ABSMult)
ELSE Exp(ABSMult)
END
FROM (SELECT
Sum(Log(Abs(NULLIF(Value, 0)))) AS ABSMult,
Sum(Sign(CASE
WHEN Value < 0 THEN 1
ELSE 0
END)) AS Neg,
Min(Abs(Value)) AS MinVal
FROM @values) foo
RETURN @mul_value
END
và gọi nó là:
SELECT *
FROM Floats a
CROSS APPLY (SELECT dbo.udf_mul((SELECT [value]
FROM Floats b
WHERE a.id >= b.id
FOR XML PATH, ROOT('root')))
AS r) as cs(r);
Đầu ra:
╔═════╦════════╦════════════════════╗
║ id ║ value ║ r ║
╠═════╬════════╬════════════════════╣
║ 1 ║ 1 ║ 1 ║
║ 2 ║ 3 ║ 3.0000000000000004 ║
║ 3 ║ 6 ║ 17.999999999999996 ║
║ 4 ║ 2 ║ 36 ║
╚═════╩════════╩════════════════════╝