Click here to Skip to main content
15,921,371 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey,

I have a couple of products in my db. some are priced in bands and others are priced in stepped bands based on quantity:

banding (not stepped)
productA: 1-5 = £25, 6-10 = £22
so if you buy 5 then all are £25 (£125) but if you buy 6 then all are £22 (£132)

stepped banding
productB: 1-5 = £105, 6-10 = £100
so if you buy 6, the first 5 are £105 but the 6th (or 7th, 8th etc) are at £100
5*105+(6-5)*100

is there a "neat"* way to do this?

thanks ^_^
Andy
*Neat:
Quote:
1.arranged in a tidy way; in good order.
2.done with or demonstrating skill or efficiency.


What I have tried:

So here is what I have so far:
SQL
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


I get the pricing band qtys in a view:
SQL
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
Posted
Updated 29-Jun-16 8:23am

Hey Andy,

I find it hard to think of anything very neat with the distinctly different forms of price banding (stepped and not stepped).

The (neat) solution might be by describing one type of pricing in the terms of the other. Doing this would neaten your data and make the price calculations nice. You can still, of course, in the external / presentation layer describe it in terms of stepped / not stepped.

Here's what I mean: Imagine the following stepped banding:

product A:
1-5 = 25
6 = 7
7-10 = 22

This works out exactly the same total as the price in your example (6 are 132 = 5*25+1*7) but the data is described in the terms of a stepped banding.

Once this is done, the SQL becomes standard joins on a banding.

Hope this helps!?

Jon
 
Share this answer
 
v2
Comments
Andy Lanng 30-Jun-16 6:52am    
Hi Jon,

I blame myself but this is not an answer to my question. What you describe above seems to be an alternative solution to the banding without stepping. You did give me a good idea though ^_^
If I've understood your question correctly, and assuming your price-bands are well defined (no overlaps or gaps), then something like this should work:
SQL
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
;

If that's not right, can you create a SQL Fiddle[^] with some dummy sample data to demonstrate?
 
Share this answer
 
Comments
Andy Lanng 30-Jun-16 6:53am    
Spot on, sir! I was close to this myself but just couldn't pull it together.
Thanks for the help ^_^

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900