Выражения в представлениях SQL - PullRequest
4 голосов
/ 21 января 2011

Я новичок в представлениях 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]

будет использоваться вместо того, чтобы переписывать его.

например, чтобы я мог использовать:

[Pack Cost] / [Units]

Для определения стоимости единицы вместо:

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

Не уверен, что я получаю правильный конец палки, или это уместно.

Ответы [ 6 ]

3 голосов
/ 28 января 2011

Создайте новую пользовательскую скалярную функцию следующим образом:

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 голосов
/ 21 января 2011

Вы можете создать скалярную функцию, которая сделает эту логику за вас.Тогда вы можете просто вызвать функцию в вашем представлении.

1 голос
/ 21 января 2011

Вы можете определить его в подзапросе

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
1 голос
/ 21 января 2011

Создание промежуточного представления с логикой расчета. Назовите это (например) ProductEx. В этом представлении столбец PackCost может быть рассчитан и назван для вас. Затем напишите все ваши другие представления вместо представления ProductEx вместо таблицы Product.

0 голосов
/ 28 января 2011

Кроме того, если вы будете часто выполнять вычисления, вы можете добавить вычисленное поле в исходную таблицу, которая называется PackCost.тогда caclis выполняется только при вводе данных или изменяется не при каждом запросе.

0 голосов
/ 21 января 2011

Мой опыт показывает, что «стоимость» приобретения строк настолько велика по сравнению со стоимостью выполнения простых вычислений, что мне просто наплевать на это. Я бы сказал, что удобочитаемость и / или абстракция имеют большее значение.

Плюс, вполне вероятно, что ваши базы данных уже выполняют эти оптимизации под капотом, но вы должны измерить оба способа, чтобы быть уверенными.

...