我使用SQL Server 2008。 我尝试做一个报告,并需要计算我的表的每一行的新列。 我写这个函数:如何优化此SQL脚本
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
ALTER FUNCTION [dbo].[fn_CalcProductStock]
(
@ProductID INT = NULL ,
@ToDate DATETIME = NULL ,
@FinYear INT = NULL ,
@InventoryID INT = NULL
)
RETURNS FLOAT
AS
BEGIN
DECLARE @stock FLOAT
SET @stock = ISNULL((SELECT SUM(IDI.InvDocItemNumbers)
FROM InvDocItem IDI
LEFT OUTER JOIN InvDoc ID ON IDI.CenterID = ID.CenterID
AND IDI.InvDocID = ID.InvDocID
WHERE IDI.ProductID = @ProductID
AND ID.FinYearID = @FinYear
AND (ID.InventoryID = @InventoryID
OR @InventoryID IS NULL
)
AND ID.InvDocDate < @ToDate
AND (ID.InvTransTypeID = 1
OR ID.InvTransTypeID = 4
OR ID.InvTransTypeID = 6
OR ID.InvTransTypeID = 13
OR ID.InvTransTypeID = 9
)
), 0)
- ISNULL((SELECT SUM(II.InvoiceItemNumbers)
FROM InvoiceItem II
LEFT OUTER JOIN Invoice I ON (II.CenterID = I.CenterID
AND II.InvoiceID = I.InvoiceID
)
WHERE II.ProductID = @ProductID
AND I.FinYearId = @FinYear
AND I.InvoiceDate < @ToDate
AND (I.InventoryID = @InventoryID
OR @InventoryID IS NULL
) --Tehran:1 Tehrantakh:101 Mashhad:21 Tabriz:6
AND (I.InvoiceType = 1
OR I.InvoiceType = 3
)
), 0)
+ ISNULL((SELECT SUM(II.InvoiceItemNumbers)
FROM InvoiceItem II
LEFT OUTER JOIN Invoice I ON II.CenterID = I.CenterID
AND II.InvoiceID = I.InvoiceID
WHERE II.ProductID = @ProductID
AND I.FinYearId = @FinYear
AND I.InvoiceDate < @ToDate
AND (I.InventoryID = @InventoryID
OR @InventoryID IS NULL
)
AND (I.InvoiceType = 2
OR I.InvoiceType = 4
)
), 0)
- ISNULL((SELECT SUM(IDI.InvDocItemNumbers)
FROM InvDocItem IDI
LEFT OUTER JOIN InvDoc ID ON IDI.CenterID = ID.CenterID
AND IDI.InvDocID = ID.InvDocID
WHERE IDI.ProductID = @ProductID
AND ID.InvTransTypeID = 3
AND ID.FinYearID = @FinYear
AND (ID.InventoryID = @InventoryID
OR @InventoryID IS NULL
)
AND ID.InvDocDate < @ToDate
), 0)
-- Return the result of the function
RETURN @stock
END
也是我尝试在这种情况下使用此fonction:
SELECT Prdct.InventoryID ,
Prdct.ProductID ,
(dbo.fn_CalcProductStock(Prdct.ProductID, '2014-04-29', 92, 101))
FROM ProductInv AS Prdct
这有真正的计算结果,但需要很长一段时间 像40分钟...! !对于3000产品
我该如何使其性能更好?
除了任何性能问题,您的功能可能**不**按照您的意愿行事。唯一可以忽略的变量是'InventoryId'。 “FinYear”和“ToDate”将需要返回_any_结果的值。 'ProductId'条件的定位意味着连接实际上是'INNER JOIN's - 如果你不提供一个值,你也不会得到结果(因为'null'_does not equal_' null')。你的查询似乎获得了一个_quantity_的项目,但对我来说'ItemNumber'本质上是一个**键** - 这是一个含糊不清的命名变量,还是它是一个计数? –
它是每个产品在发票或文档中的计数.. – merkousha