Andy Lanng Ответов: 2

Как я могу рассчитать "ступенчатую" цену в SQL?


Эй,

У меня есть несколько продуктов в моей БД, некоторые из них оцениваются в диапазонах, а другие - в ступенчатых диапазонах, основанных на количестве:

окантовка (не ступенчатая)
productA: 1-5 = £25, 6-10 = £22
Итак, если вы покупаете 5, то все они стоят 25 фунтов (125 фунтов), но если вы покупаете 6, то все они стоят 22 фунта (132 фунта)

ступенчатая окантовка
productB: 1-5 = £105, 6-10 = £100
Итак, если вы покупаете 6, то первые 5 стоят 105 фунтов, а 6-й (или 7-й, 8-й и т. д.) - 100 фунтов
5*105+(6-5)*100

есть ли " аккуратный"* как это сделать?

спасибо ^_^
Энди
*Аккуратный:
Цитата:
1. упорядочено в аккуратном порядке; в хорошем порядке.
2. сделано с демонстрацией мастерства или эффективности.


Что я уже пробовал:

Итак, вот что у меня есть до сих пор:
select 
	c.company_id,
	c.company_name,
	b.pricing_price,
	p.product_name,
	l.licence_quantity,
	b.pricing_price * l.licence_quantity as company_cost
from company c
inner join licence l on c.company_id = l.licence_companyid
inner join product p on l.licence_productid = p.product_id
inner join price_banding b on l.licence_productid = b.pricing_productid
where 
	b.pricing_band_min<=l.licence_quantity and 
	(b.pricing_band_max >= l.licence_quantity or b.pricing_band_max is null) and 
	b.pricing_stepped = 0


Я вам ценовой группы количество в вид:
with banding as(
	select  
		p.pricing_id, 
		p.pricing_productid, 
		p.pricing_band_min, 
		p2.pricing_band_min-1 as pricing_band_max,
		p.pricing_price,
		p.pricing_stepped,
		row_number() over (partition by p.pricing_productid,p.pricing_band_min  order by p2.pricing_band_min-1) as num
	from pricing p
	left outer join pricing p2 on p.pricing_productid = p2.pricing_productid and p.pricing_band_min<p2.pricing_band_min
)
select 
	p.pricing_id, 
	p.pricing_productid, 
	p.pricing_band_min, 
	p.pricing_band_max,
	p.pricing_price,
	p.pricing_stepped
from banding p 
where p.num = 1

2 Ответов

Рейтинг:
2

JonPoley3

Привет Энди,

Мне трудно придумать что-то очень аккуратное с отчетливо различающимися формами ценовой полосы (ступенчатой и не ступенчатой).

(Аккуратное) решение может заключаться в описании одного типа ценообразования в терминах другого. Это позволит привести ваши данные в порядок и сделать расчеты цен приятными. Вы все еще можете, конечно, во внешнем / презентационном слое описать его в терминах ступенчатого / не ступенчатого.

Вот что я имею в виду: представьте себе следующее ступенчатый кольцевание:

продукт а:
1-5 = 25
6 = 7
7-10 = 22

Это работает точно так же, как и цена в вашем примере (6 132 = 5*25+1*7) но данные описываются в терминах ступенчатой полосы.

Как только это будет сделано, SQL станет стандартным соединением на кольцевании.

Надеюсь, это поможет!?

Джон


Andy Lanng

Привет Джон,

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

Рейтинг:
10

Richard Deeming

Если я правильно понял ваш вопрос и предполагаю, что ваши ценовые диапазоны хорошо определены (без наложений и пробелов), тогда что-то вроде этого должно сработать:

WITH prices As
(
    -- Not stepped:
    -- * Only a single price band should match;
    -- * Total price = quantity * price;
    SELECT
        l.licence_companyid,
        l.licence_productid,
        l.licence_quantity,
        b.pricing_price,
        b.pricing_price * l.licence_quantity As company_cost
    FROM
        licence As l
        INNER JOIN price_banding As b
        ON b.pricing_productid = l.licence_productid
    WHERE
        b.pricing_stepped = 0
    And 
        b.pricing_band_min <= l.licence_quantity
    And
        (b.pricing_band_max >= l.licence_quantity Or b.pricing_band_max Is Null)

    UNION ALL

    -- Stepped:
    -- * Match all price bands that apply (min < quantity);
    -- * Total price = sum of [quantity for this band] * price;
    SELECT
        l.licence_companyid,
        l.licence_productid,
        Max(l.licence_quantity),
        Max(b.pricing_price),
        Sum(b.pricing_price * CASE
            WHEN b.pricing_band_max Is Null THEN 1 + l.licence_quantity - b.pricing_band_min
            WHEN b.pricing_band_max >= l.licence_quantity THEN 1 + l.licence_quantity - b.pricing_band_min
            ELSE 1 + b.pricing_band_max - b.pricing_band_min
        END)
    FROM
        licence As l
        INNER JOIN price_banding As b
        ON b.pricing_productid = l.licence_productid
    WHERE
        b.pricing_stepped = 1
    And 
        b.pricing_band_min <= l.licence_quantity
    GROUP BY
        l.licence_companyid,
        l.licence_productid
)
SELECT
    c.company_id,
    c.company_name,
    b.pricing_price,
    p.product_name,
    b.licence_quantity,
    b.company_cost
FROM
    prices As b
    INNER JOIN company As c
    ON c.company_id = b.licence_companyid
    INNER JOIN product As p
    ON p.product_id = b.licence_productid
;

Если это не так, Можете ли вы создать Скрипка SQL[^] с некоторыми фиктивными образцами данных для демонстрации?


Andy Lanng

В точку, сэр! Я и сам был близок к этому, но никак не мог взять себя в руки.
Спасибо за помощь ^_^