2011-01-20 27 views
4

我是SQL視圖的新手,所以要溫和!SQL視圖中的表達式

我有以下SQL視圖:

SELECT  dbo.product.name AS [Product Name], 
       ROUND(CASE [vat] WHEN 1 THEN [packcost] * 1.2 ELSE [packcost] END, 2) AS [Pack Cost],    
       ROUND(CASE [vat] WHEN 1 THEN ([packcost] * 1.2)/[units] ELSE [packcost]/[units] END, 2) AS [Unit Cost], 
       dbo.purchase.unitsaleprice * dbo.product.units AS [ Pack Sale Price], dbo.purchase.unitsaleprice AS [Unit Sale Price], 
       dbo.product.units * (dbo.purchase.unitsaleprice - ROUND(CASE [vat] WHEN 1 THEN ([packcost] * 1.2)/[units] ELSE [packcost]/[units] END, 2)) AS [Pack Profit], 
       dbo.purchase.unitsaleprice - ROUND(CASE [vat] WHEN 1 THEN ([packcost] * 1.2)/[units] ELSE [packcost]/[units] END, 2) AS [Unit Profit] 
      FROM dbo.product INNER JOIN 
       dbo.purchase ON dbo.product.id = dbo.purchase.productID 

但正如我重寫了很多這似乎效率不高。

例如我想限定[包費用]柱:

ROUND(CASE [vat] WHEN 1 THEN [packcost] * 1.2 ELSE [packcost] END, 2) AS [Pack Cost] 

被elswhere代替重寫它的。

例如,所以我可以使用:

[Pack Cost]/[Units] 

要定義的單位成本,而不是:

ROUND(CASE [vat] WHEN 1 THEN ([packcost] * 1.2)/[units] ELSE [packcost]/[units] END, 2) AS [Unit Cost] 

不知道如果我越來越棒的右端雖然,抑或是適合做到這一點。

回答

3

創建新的用戶定義的標量值函數如下:

CREATE FUNCTION [dbo].[GetPackCost] 
(
    @vat int 
    ,@packcost decimal 
) 
RETURNS decimal 
AS 
BEGIN 
    DECLARE @packcost_calculated decimal 

    SELECT @packcost_calculated = ROUND(CASE @vat WHEN 1 THEN @packcost * 1.2 ELSE @packcost END, 2) 

    RETURN @packcost_calculated 

END 

GO 

在您的查詢,你會選擇如下:

SELECT  dbo.product.name AS [Product Name], 
       dbo.GetPackCost([vat],[packcost]) AS [Pack Cost],    
       dbo.GetPackCost([vat],[packcost])/[units] AS [Unit Cost], 
       dbo.purchase.unitsaleprice * dbo.product.units AS [ Pack Sale Price], dbo.purchase.unitsaleprice AS [Unit Sale Price], 
       dbo.product.units * (dbo.purchase.unitsaleprice - ROUND(CASE [vat] WHEN 1 THEN ([packcost] * 1.2)/[units] ELSE [packcost]/[units] END, 2)) AS [Pack Profit], 
       dbo.purchase.unitsaleprice - ROUND(CASE [vat] WHEN 1 THEN ([packcost] * 1.2)/[units] ELSE [packcost]/[units] END, 2) AS [Unit Profit] 
      FROM dbo.product INNER JOIN 
       dbo.purchase ON dbo.product.id = dbo.purchase.productID 
2

您可以創建一個標量函數爲您執行該邏輯。然後,您可以在視圖中調用該函數。

+0

對不起,是麻木了 - 你可以給我一些更多的指針?我會創建一個返回[Pack Cost]的函數嗎? – Ben

1

用計算邏輯創建一箇中間視圖。將其稱爲(例如)ProductEx。此視圖可以爲您計算並命名PackCost列。然後將所有其他視圖寫入視圖ProductEx而不是表格Product。

0

我的經驗是,獲得行的「成本」與執行簡單計算的成本相比是非常大的,我從來不關心它。 我會說,可讀性和/或抽象是更大的關注。

另外,很可能您的dbms已經在引擎蓋下執行了這些優化,但您應該測量這兩種方法以確保。

1

您可以在子查詢中定義它

SELECT p.name AS [Product Name], 
P.[Pack Cost] AS [Pack Cost], 
Round(P.[Pack Cost]/[units],2) AS [Unit Cost], 
dbo.purchase.unitsaleprice * p.units AS [ Pack Sale Price], dbo.purchase.unitsaleprice AS [Unit Sale Price], 
p.units * (dbo.purchase.unitsaleprice - Round(P.[Pack Cost]/[units],2)) AS [Pack Profit], 
dbo.purchase.unitsaleprice - Round(P.[Pack Cost]/[units],2) AS [Unit Profit] 
FROM 
(SELECT *, [Pack Cost] = ROUND(CASE [vat] WHEN 1 THEN [packcost] * 1.2 ELSE [packcost] END, 2) FROM dbo.product) p 
INNER JOIN dbo.purchase ON p.id = dbo.purchase.productID 
0

另外,如果你時便會經常做計算,你可以一個計算方法爲字段添加到被稱爲PackCost原表。那麼caclis只會在數據輸入時完成,或者不會對每個查詢進行更改。