SQL视图中的表达式

时间:2011-01-20 21:29:10

标签: sql sql-server view

我是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

但是,由于我正在重写其中很多内容,这似乎效率低下。

例如,我想定义[Pack Cost]列:

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]

不确定我是否得到了棒的右端,或者是否适合这样做。

6 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

您可以创建一个为您执行该逻辑的标量函数。然后你可以在视图中调用该函数。

答案 2 :(得分:1)

使用计算逻辑创建中间视图。称之为(例如)ProductEx。此视图可以为您计算和命名PackCost列。然后针对视图ProductEx而不是表Product。编写所有其他视图。

答案 3 :(得分: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

答案 4 :(得分:0)

我的经验是,与执行简单计算的成本相比,获取行的“成本”是如此之大,而我从不关心它。 我要说可读性和/或抽象是更值得关注的。

另外,您的dbms可能已经在底层执行了这些优化,但您应该测量两种方式以确保。

答案 5 :(得分:0)

或者,如果您经常进行计算,则可以将一个计算字段添加到名为PackCost的原始表中。然后caclis只在数据输入时完成,或者不是每次查询都改变。