问题是我有一个特定购买订单的多个寄存器,因为每个寄存器都属于同一购买中的不同产品,首先我要执行以下功能:
CREATE FUNCTION TOTALORDEN (@id_orden INT)
RETURNS float
AS
BEGIN
DECLARE @total FLOAT
SELECT @total = UnitPrice * Quantity - UnitPrice * Quantity * Discount
FROM [Order Details]
WHERE @id_orden = OrderID
RETURN @total
END
但是该函数的问题是仅打印最后一个寄存器的结果。
然后我决定在select指令上使用SQL算术,函数是这样的:
CREATE FUNCTION TOTALORDEN (@id_orden INT)
RETURNS table
RETURN (SELECT (UnitPrice * Quantity) -
(UnitPrice * Quantity * Discount)
FROM [Order Details]
WHERE @id_orden = OrderID)
它显示的错误是:
第3行,TOTALORDEN程序,第16级,状态1,消息4514
CREATE FUNCTION产生错误,因为没有为第1列指定列名。
表中的部分数据:
答案 0 :(得分:1)
我猜你错过了聚合函数SUM()
DECLARE @total float
SELECT @total= SUM (UnitPrice*Quantity-UnitPrice*Quantity*Discount)
FROM [Order Details]
WHERE @id_orden=OrderID
RETURN @total
答案 1 :(得分:1)
SQL不喜欢它,则返回的列是命名的。我使用了FinalPrice的列名,您可以将其更改为您想要的名称。此外,如果您打算使用此功能更新表等,则在表中返回orderid会很有帮助。这应该可以工作:
CREATE FUNCTION [TOTALORDEN] ( @id_orden INT )
RETURNS TABLE
RETURN
(
SELECT OrderId, SUM(( [UnitPrice] * [Quantity] ) - ( [UnitPrice] * [Quantity] * [Discount]) ) AS FinalPrice
FROM
[Order Details]
WHERE [OrderID] = @id_orden
Group BY OrderId
)
此外,如果您只需要返回总订单金额,那么使用表值函数是一个过大的选择。您应该使用
CREATE FUNCTION [TOTALORDEN] ( @id_orden INT )
RETURNS FLOAT
AS
BEGIN
DECLARE @total FLOAT
SELECT
@total = SUM (([UnitPrice] * [Quantity]) - ([UnitPrice] * [Quantity] * [Discount]))
FROM
[Order Details]
WHERE [OrderID] = @id_orden
RETURN @total
END
也不建议在表名中使用空格,您也应该考虑对其进行重构
答案 2 :(得分:0)
SQL Server标量函数在SQL Server中表现不佳,应尽量避免使用它们。内联表值函数更好,但是在这种情况下,我希望使用类似以下的视图:
CREATE VIEW OrderDetailsSummary
WITH SCHEMABINDING
AS
SELECT od.OrderID, SUM (ISNULL(od.Quantity * od.UnitPrice * (1 - CAST(od.Discount AS money)), 0)) as OrderTotal, COUNT_BIG(*) AS OrderLineCount
FROM
dbo.OrderDetails od
GROUP BY
od.OrderID
GO
此视图可以被索引,使其闪电般快速:
CREATE UNIQUE CLUSTERED INDEX UX_OrderDetailsSummary
ON OrderDetailsSummary(OrderID)
您现在可以通过一个简单的查询来获取订单总数和订单行数:
SELECT *
FROM OrderDetailsSummary WITH (NOEXPAND)
WHERE OrderID = 10260
这是非常有效的。我只需要2个逻辑读取:
(受影响的1行)表'OrderDetailsSummary'。扫描计数0,逻辑 读取2,物理读取0,预读0,lob逻辑读取0, lob物理读取为0,lob提前读取为0。
这是执行计划:
此外,该视图可以与其他视图和表联接。例如,您可以获取订单信息以及摘要数据:
SELECT O.OrderID, O.CustomerID, O.OrderDate, S.OrderTotal, S.OrderLineCount
FROM
dbo.Orders O
LEFT OUTER JOIN dbo.OrderDetailsSummary S WITH (NOEXPAND)
ON O.OrderID = S.OrderID