Reputation: 3549
I'm building a commission calculator, and I'm not sure how to proceed. I have situations like: saleRep A for customer 123 gets 2% for the first 2 years, then .5% thereafter. I already know how to get the age of the customer.
And the date ranges are variable. Meaning that one salesRep/Customer combination could split at 1 year, 2 years, anytime, but probably on the year.
So, how do I query for and store this? My commission table is currently as follows, do I need to change it?
CREATE TABLE [dbo].[NCL_Commissions](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ProductType] [varchar](255) NULL,
[LowCost] [int] NULL,
[HighCost] [int] NULL,
[CustCode] [varchar](30) NULL,
[SalesRep] [varchar](10) NULL,
[Commission] [float] NULL,
[MinAge] [smallint] NULL,
[MaxAge] [smallint] NULL,
CONSTRAINT [PK_NCL_Commissions] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Here's how I built it when I was told all commissions would be the same:
DECLARE @custCreationDate datetime
SET @custCreationDate = ( SELECT TOP 1 cast(INVDate as datetime)
FROM InvoiceHeader
WHERE companycode = @custCode
order by recid asc )
-- PRINT 'Line 54: @custCreationDate: ' + cast(@custCreationDate as varchar)
--If the customer has existed for less than a year
IF @custCreationDate > DateAdd(yy, -1, @now)
BEGIN
SET @result = 2.00 --Customers in existance for less than a year yeild 2% commission
-- PRINT 'Line 60 - @result: ' + cast(@result as varchar)
GOTO Exit_Function
END
ELSE
BEGIN
SET @result = 0.50 --Customers in existance longer yeild 0.5 % commission.
-- PRINT 'Line 66 - @result: ' + cast(@result as varchar)
GOTO Exit_Function
END
Sample Data (part of question is looking for suggestions on how to store)
Customer 123 for salesrep A gets 1% for the first 2 years, than .5%
Customer 456 for salesrep B gets 2% for the first 1 year, than .75%
At any given time, I have to be able get the correct percentage based on the current age of the customer. So if customer A was created June 1 2012, commision is 2%. If customer was created Sept 5 2008, then commission is .5%.
SOLUTION Based on Gordon Linoff's answer:
SET @custAgeInMonths = datediff(month, @custCreationDate, @invDate)
--First look for a customer specific record
SELECT @result = C.Commission
FROM NCL_Commissions C
WHERE C.CustCode = @custCode
AND C.SalesRep = @salesRep
AND ProductType in ('L')
AND @custAgeInMonths BETWEEN C.MinAgeMonths AND C.MaxAgeMonths
Upvotes: 1
Views: 181
Reputation: 180
1) you need a table that has the commissions brackets (i recommend by month)
CREATE TABLE [dbo].[CommissionsBrakets](
[ID] [int] NOT NULL,
[Commission] [Decimal](4, 4) NULL,
Month [smaillint])
fill it with the brakets
1 2% 1 /month 1 2%
1 2% 2 /month 2 2%
....
1 0.5% 24 /month 24 (2 years) 0.5%
2) you need a table relating costumer+salesrep+comisionBracket
CREATE TABLE [dbo].[NCL_Commissions](
[ID] [int] IDENTITY(1,1) NOT NULL,
[CustCode] [varchar](30) NULL,
[SalesRep] [varchar](10) NULL,
[CommissionID] [int] NULL)
then you can do a join
declare @mothDiff int = DATEDIFF(m, @custCreationDate, GETDATE())
Select b.Commission from NCL_Commissions C inner join CommissionsBrakets B
on c.CommissionID = B.ID
where
B.month = case
when @mothDiff > ((select max(Month) from CommissionsBrakets CB where CB.id = B.ID ))
then (select max(Month) from CommissionsBrakets CB where CB.id = B.ID )
else @mothDiff
end
Upvotes: 0
Reputation: 1270371
This seems like a join.
Assume you have a customer table, with the start date of the customer and the commission table above. You can calculate the current age of the customer and join into the commission table. This assumes that the customer record has the sales rep:
select <whatever>
from (select c.*, datediff(day, c.joindate, getdate())/365.25 as AgeYears
from customer c
) c left outer join
NCL_Commissions com
on c.CustCode = com.CustCode and
c.ProductType= com.ProductType and
c.SalesRep = com.SalesRep and
c.AgeYears between MinAge and c.MaxAge
Given all the join criteria, I would watch out for non-matches (hence the use of the left outer join).
Upvotes: 1