Home > Enterprise >  SQL Help, Splitting Tax by Tenders
SQL Help, Splitting Tax by Tenders

Time:03-30

I have a Point of Sale system where all checks and tender details exist in a single table. I'm trying to write a SQL query in a way that I can see check totals by tenders to reconcile with cash flow and bank statements. Unfortunately the schema is not mine and can't change it.

One problem I ran into is that there are cases where one check has multiple transactions involving various tenders, therefore I need to do implement (business set) rules to allocate taxes evenly. Those rules might change in the future to say, allocate taxes to CC first if any, so I need to built in some flexibility.

The SQL table looks like this:

CheckID LineType TenderName LineTotal Tax
1 ItemSold 5.00 0.25
1 TenderTotal Cash 5.25
2 ItemSold 10.00 0.50
2 TenderTotal Cash 5.00
2 TenderTotal VISA 5.50
3 ItemSold 10.00 0.25
3 ItemSold 10.00 0.25
3 TenderTotal AMEX 10.25
3 TenderTotal VISA 10.25
4 ItemSold 10.00 0.50
4 TenderTotal Cash 20.00
4 TenderTotal Cash -9.50

The resulting report needs to have one row per tender, with tax equally distributed among check tenders, and net revenue being the difference between total sale and tax.

TenderName TotalSale NetRevenue TaxCollected
Cash 20.75 19.75 1.00
VISA 15.75 15.25 0.50
AMEX 10.25 10.00 0.25

I tried using Select with Exists, also CTE and recursive CTEs, but can't quite figure it out how to do the tax part cleanly. Any other SQL tricks I could try?

We are using SQL Server 2012 at the moment, but have plans in plan to upgrade to 2016 in the near future.

CodePudding user response:

I don't know if the logic is right, but it gets you the results you are after:

WITH Tenders AS(
    SELECT V.CheckID,
           V.LineType,
           V.TenderName,
           V.LineTotal,
           SUM(CASE WHEN V.TenderName IS NULL THEN V.Tax END) OVER (PARTITION BY V.CheckID) AS Tax
    FROM (VALUES(1,'ItemSold',NULL,5.00,0.25),
                (1,'TenderTotal','Cash',5.25,NULL),
                (2,'ItemSold',NULL,10.00,0.50),
                (2,'TenderTotal','Cash',5.00,NULL),
                (2,'TenderTotal','VISA',5.50,NULL),
                (3,'ItemSold',NULL,10.00,0.25),
                (3,'ItemSold',NULL,10.00,0.25),
                (3,'TenderTotal','AMEX',10.25,NULL),
                (3,'TenderTotal','VISA',10.25,NULL),
                (4,'ItemSold',NULL,10.00,0.50),
                (4,'TenderTotal','Cash',20.00,NULL),
                (4,'TenderTotal','Cash',-9.50,NULL))V(CheckID,LineType,TenderName,LineTotal,Tax))
SELECT T.TenderName,
       SUM(T.LineTotal) AS TotalSale,
       SUM(T.LineTotal - T.Tax) AS NetRevenue,
       SUM(T.Tax) AS TaxCollected
FROM Tenders T
WHERE T.TenderName IS NOT NULL
GROUP BY T.TenderName;
  • Related