Intelligent Enterprise

Better Insight for Business Decisions

Intelligent Enterprise - Better Insight for Business Decisions
search Intelligent Enterprise
Advanced Search
RSS
Webcasts
Digital Library
Subscribe
Home



Celko SQL Puzzle: Calculating Commissions | Intelligent Enterprise Blog
E-MAIL  |  
Share
Celko SQL Puzzle: Calculating Commissions

Posted by Joe Celko
Tuesday, September 2, 2008
3:10 PM

I discussed a number of ways to split commissions among multiple salespeople in this article, but can you come up with other ways to keep track of the commission amounts? I'll give you a hint; ask yourself, "what is the simplest fact in this problem?"

One way of spotting a design problem is when you have to use a VIEW or CTE over and over to answer basic questions. This implies that the schema has spread information over many tables that should be in one table or that it has aggregated data in one row that should be split out into multiple rows.

The schema is a mess. Attributes of a sales commission are split over multiple tables, so we ought to consolidate things in one place. The design below copies paper input forms that showed the total but did not breakdown the associated commissions.

CREATE TABLE SalesCommissions
(sale_nbr INTEGER NOT NULL,
 cust_id VARCHAR(10) NOT NULL,
 salesperson_id VARCHAR(20) NOT NULL,
 commission_amt DECIMAL(12,4) NOT NULL,
 PRIMARY KEY (sale_nbr, cust_id, salesperson_id));

The total of each sale has to be derived in a VIEW. The VIEW will now balance to the commission amounts.

CREATE VIEW Sales (sale_nbr, cust_id, sales_amt)
AS
SELECT sale_nbr, cust_id, SUM(commission_amt)
 FROM SalesCommissions
 GROUP BY sale_nbr, cust_id;

One trick is to put the division of the spoils in a stored procedure that inserts an equal division into the SalesCommissions instead of trying to get it into a VIEW.

CREATE PROCEDURE PostCommissions
(IN my_sale_nbr INTEGER,
 IN my_cust_id VARCHAR(10),
 IN my_sales_amt DECIMAL(12,4),
--list of participating salespersons, say up to 5
 IN salesperson_id_1 VARCHAR(20),
 IN salesperson_id_2 VARCHAR(20),
 IN salesperson_id_3 VARCHAR(20),
 IN salesperson_id_4 VARCHAR(20),
 IN salesperson_id_5 VARCHAR(20))
LANGUAGE SQL
DETERMINISTIC
BEGIN
-- LOCAL TEMPORARY TABLE X ..ON COMMIT DELETE ROWS
INSERT INTO X (salesperson_id)
SELECT DISTINCT X.salesperson_id
     FROM (VALUES (salesperson_id_1),
       COALESCE (salesperson_id_2, salesperson_id_1),
       COALESCE (salesperson_id_3, salesperson_id_1),
       COALESCE (salesperson_id_4, salesperson_id_1),
       COALESCE (salesperson_id_5, salesperson_id_1));

INSERT INTO SalesCommissions
(sale_nbr, cust_id, salesperson_id, commission_amt)
 SELECT my_sale_nbr, my_cust_id, X.salesperson_id,
    my_sales_amt / (SELECT COUNT(*) FROM X)
  FROM X;
COMMIT;
END;

It would be nice to make X into a CTE, but I do not know of any SQL product that can do that yet. This procedure is good for up to a five-away split. The pattern for adding more and more salespeople is obvious. The use of SELECT DISTINCT will also allow a salesperson's id to be input twice without causing an error. In the real world, there are probably more business rules for dividing the Spoils based on seniority, the items purchased and so forth.



E-MAIL  |  
Share




This is a public forum. United Business Media and its affiliates are not responsible for and do not control what is posted herein. United Business Media makes no warranties or guarantees concerning any advice dispensed by its staff members or readers.

Community standards in this comment area do not permit hate language, excessive profanity, or other patently offensive language. Please be aware that all information posted to this comment area becomes the property of United Business Media LLC and may be edited and republished in print or electronic format as outlined in United Business Media's Terms of Service.

Important Note: This comment area is NOT intended for commercial messages or solicitations of business.


 




    Subscribe to RSS feed of all blogs


 



Techweb
Informationweek Business Technology Network
InformationweekInformationweek 500Informationweek 500 ConferenceInformationweek AnalyticsInformationweek Events
Informationweek MagazineGlobal CIOIWK Government ITbMightyByte and SwitchDark Reading
Digital LibraryIntelligent EnterpriseInternet EvolutionNetwork ComputingPlug Into The CloudDr. DobbsContentinople
space
TechWeb Events Network
InteropVoiceConWeb 2.0 ExpoWeb 2.0 SummitEnterprise 2.0Mobile Business ExpoNoJitter
Black HatGTECEnergy CampCloud ConnectGov 2.0 ExpoGov 2.0 Summit
space
Light Reading Communications Network
Light ReadingLight Reading AsiaUnstrungCable Digital NewsInternet EvolutionPyramid Research
Heavy ReadingLight Reading LiveLight Reading InsiderEthrnet ExpoTelco TVTower Technology Summit
space
Financial Technology Network
Advanced TradingBank Systems and TechnologyInsurance and TechnologyWall Street and TechnologyAccelerating WallstreetBST SummitBuyside Trading SummitIT Summit
space
Microsoft Technology Network
MSDNTechNetTotal IT ProTotal Dev ProNET Total Dev Pro CommunitySQL Total Dev Pro Community
space