2016-08-05 2 views
0

Таблица схемы:Расчет цены на основе блока вошли

CREATE TABLE [dbo].[TblPriceDetails](
    [PriceID] [int] IDENTITY(1,1) NOT NULL, 
    [VID] [int] NOT NULL, 
    TypeID int not null, 
    [RangeStart] [decimal](18, 3) NOT NULL, 
    [RangeEnd] [decimal](18, 3) NOT NULL, 
    [Price] [decimal](18, 2) NOT NULL, 
    [ExtraLoad] [decimal](18, 3) NULL, 
    [ExtraPrice] [decimal](18, 2) NULL 
) 
GO 

образца данных

Insert into dbo.TblPriceDetails values (1,1, 0,0.250,10,0,0) 
Insert into dbo.TblPriceDetails values (1,1, 0.251,0.500,15,0.500,15) 
Insert into dbo.TblPriceDetails values (1,1, 3,5,40,1,25) 
GO 
Insert into dbo.TblPriceDetails values (1,2, 0,0.250,15,0,0) 
Insert into dbo.TblPriceDetails values (1,2, 0.251,0.500,20,0.500,20) 
Insert into dbo.TblPriceDetails values (1,2, 3,5,50,1,30) 
GO 

Ожидаемый результат:

Для VID = 1 и TypeID = 1 и заданное значение 0,300

  • По мере того как входной блок попадает между RangeStart 0,251 и RangeEnd 0,500 результирующая цена будет 15

Для VID = 1 и TypeID = 1 и заданное значение 0,600

  • Согласно данным до 0,500, цена составляет 15 и для каждой дополнительной нагрузки до 0,500 ее другой 15. Таким образом, окончательная цена составит 30

Для VID = 1 и TypeID = 1 и заданное значение 1,500

  • Согласно данным до 0,500 цена не является 15. Для каждого дополнительного 0,500 его еще 15, так что для оставшихся 1 устройство было бы 15 * 2. окончательная цена будет 45

Для VID = 1 и TypeID = 1 и заданное значение 5,5

  • Согласно данным до 5.000 цена не является 40. Для каждого дополнительного 1 единицу его другой 25, так что окончательная цена будет 65

Нужна помощь в написании запроса для этого. В отличие от моих других вопросов у меня пока нет запроса, чтобы показать, что я придумал до сих пор. На данный момент я не могу создать логику и предложить общий запрос для этого.

ответ

1

Похоже, что вы хотите рассчитать стоимость доставки. Трюк состоит в том, чтобы присоединиться к RangeStart следующего весового уровня. LEAD поможет вам сделать это:

;WITH 
    AdjustedPriceDetails AS 
    (
     SELECT  VID, TypeID, RangeStart, RangeEnd, Price, ExtraLoad, ExtraPrice 
       , ISNULL(LEAD(RangeStart, 1) OVER (PARTITION BY VID, TypeID ORDER BY RangeStart), 1000000) AS NextRangeStart 
     FROM  TblPriceDetails 
    ) 


SELECT  T.* 
     , A.Price + IIF(T.Value <= A.RangeEnd, 0, CEILING((T.Value - A.RangeEnd)/A.ExtraLoad) * A.ExtraPrice) 
              AS FinalPrice 
FROM  #TestData    T 
INNER JOIN AdjustedPriceDetails A  ON A.RangeStart <= T.Value AND T.Value < A.NextRangeStart 

Объяснение:

  • LEAD(RangeStart, 1) OVER (PARTITION BY VID, TypeID ORDER BY RangeStart) получает RangeStart следующего ряда, который имеет тот же VID и TypeID
  • Вы в конечном итоге достичь наибольшего веса яруса. Таким образом, ISNULL(..., 1000000), кажется, заканчивается на уровне 1M. 1M - это просто для бесконечности.

Edit:, если вы хотите, чтобы сделать эту работу с SQL Server 2008, измените КТР:

;WITH 
    tmp AS 
    (
     SELECT  VID, TypeID, RangeStart, RangeEnd, Price, ExtraLoad, ExtraPrice 
       , ROW_NUMBER() OVER (PARTITION BY VID, TypeID ORDER BY RangeStart) AS RowNumber 
     FROM  TblPriceDetails 
    ), 
    AdjustedPriceDetails AS 
    (
     SELECT  T1.VID, T1.TypeID, T1.RangeStart, T1.RangeEnd, T1.Price, T1.ExtraLoad, T1.ExtraPrice 
       , ISNULL(T2.RangeStart, 1000000) AS NextRangeStart 
     FROM  tmp  T1 
     LEFT JOIN tmp  T2 ON T1.VID = T2.VID AND T1.TypeId = T2.TypeID AND T1.RowNumber + 1 = T2.RowNumber 
    ) 

Если вам интересно, что #TestData это (возможно, не понадобится)

CREATE TABLE #TestData 
(
     VID   int 
,  TypeID  int 
,  Value  float 
) 

INSERT INTO #TestData 
      (VID, TypeID, Value) 
    VALUES (1, 1, 0.3) 
     , (1, 1, 0.6) 
     , (1, 1, 1.5) 
     , (1, 1, 5.5) 
+0

Спасибо за ваше время. Я проголосовал за ваш ответ. Он отлично работает в последней версии SQL. Но я считаю, что функция LEAD не будет присутствовать в SQL Server 2008 R2. Любая другая альтернатива для этой работы в 2008 R2 также? – prasanth

+0

Да, только более подробный. Я отредактировал свой ответ –

+0

Обновленный код вызывает эту ошибку - Неправильный синтаксис рядом с ')'. – prasanth

Смежные вопросы