繁体   English   中英

如何在SQL Server函数中指定列名?

[英]How to specify a column name in a SQL Server function?

问题是我有一个特定购买订单的多个寄存器,因为每个寄存器都属于同一购买中的不同产品,首先我要执行以下功能:

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)

它显示的错误是:

Msg 4514,第16级,状态1,程序TOTALORDEN,第3行
CREATE FUNCTION产生错误,因为未为列1指定任何列名。

表中的部分数据:

在此处输入图片说明

我猜你错过了聚合函数SUM()

DECLARE @total float

SELECT @total= SUM (UnitPrice*Quantity-UnitPrice*Quantity*Discount) 
FROM [Order Details] 
WHERE @id_orden=OrderID

RETURN @total

如果您不告诉它返回的列的名称,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

也不建议在表名中使用空格,您也应该考虑对其进行重构

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行)表'OrderDetailsS​​ummary'。 扫描计数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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM