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.
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;
I have a problem. I am not understanding that how to deduct the quantity from stock after sale and we have multiple entries of same stock
like:
id
Medicine
Company
quantity
item price
is deleted
1
Panadol
Abbott
200
10.00
0
2
Panadol
Abbott
100
11.00
0
3
Panadol
Abbott
100
12.00
0
now how to deduct the quantity of stock and one thing is more that this product/Medicine has separate manufacturing and expiry date
please tell me how to handle it.
I was thinking that to make separate table for tracking the remaining stock quantity.
or runtime management to calculate all the sale quantity minus(-) sum of all quantities entered to get
the current stock quantity.
Please guide me.
I am dealing with a sales order table (ORDER) that looks roughly like this (updated 2018/12/20 to be closer to my actual data set):
SOID SOLINEID INVOICEDATE SALESAMOUNT AC
5 1 2018-11-30 100.00 01
5 2 2018-12-05 50.00 02
4 1 2018-12-12 25.00 17
3 1 2017-12-31 75.00 03
3 2 2018-01-03 25.00 05
2 1 2017-11-25 100.00 17
2 2 2017-11-27 35.00 03
1 1 2017-11-20 15.00 08
1 2 2018-03-15 30.00 17
1 3 2018-04-03 200.00 05
I'm able to calculate the average sales by SOID and SOLINEID:
SELECT SUM(SALESAMOUNT) / COUNT(DISTINCT SOID) AS 'Total Sales per Order ($)',
SUM(SALESAMOUNT) / COUNT(SOLINEID) AS 'Total Sales per Line ($)'
FROM ORDER
This seems to provide a perfectly good answer, but I was then given an additional constraint, that this count be done by year and month. I thought I could simply add
GROUP BY YEAR(INVOICEDATE), MONTH(MONTH)
But this aggregates the SOID and then performs the COUNT(DISTINCT SOID). This becomes a problem with SOIDs that appears across multiple months, which is fairly common since we invoice upon shipment.
I want to get something like this:
Year Month Total Sales Per Order Total Sales Per Line
2018 11 0.00
The sore thumb sticking out is that I need some way of defining in which month and year an SOID will be aggregated if it spans across multiple ones; for that purpose, I'd use MAX(INVOICEDATE).
From there, however, I'm just not sure how to tackle this. WITH? A subquery? Something else? I would appreciate any help, even if it's just pointing in the right direction.
You should select Year() and month() for invocedate and group by
SELECT YEAR(INVOICEDATE) year
, MONTH(INVOICEDATE) month
, SUM(SALESAMOUNT) / COUNT(DISTINCT SOID) AS 'Total Sales per Order ($)'
, SUM(SALESAMOUNT) / COUNT(SOLINEID) AS 'Total Sales per Line ($)'
FROM ORDER
GROUP BY YEAR(INVOICEDATE), MONTH(INVOICEDATE)
Here are the results, but the data sample does not have enuf rows to show Months...
SELECT
mDateYYYY,
mDateMM,
SUM(SALESAMOUNT) / COUNT(DISTINCT t1.SOID) AS 'Total Sales per Order ($)',
SUM(SALESAMOUNT) / COUNT(SOLINEID) AS 'Total Sales per Line ($)'
FROM DCORDER as t1
left join
(Select
SOID
,Year(max(INVOICEDATE)) as mDateYYYY
,Month(max(INVOICEDATE)) as mDateMM
From DCOrder
Group By SOID
) as t2
On t1.SOID = t2.SOID
Group by mDateYYYY, mDateMM
mDateYYYY mDateMM Total Sales per Order ($) Total Sales per Line ($)
2018 12 87.50 58.33
I have used new SQL still MAX(INVOICEDATE)(not above), with new 12/20 data, and excluded AC=17.
YYYY MM Total Sales per Order ($) Total Sales per Line ($)
2017 11 35.00 35.00
2018 1 100.00 50.00
2018 4 215.00 107.50
2018 12 150.00 75.00
I have these columns in my table
Person Agent Unit BSP Discount
578 0 000023 32689525 0.1
578 1 000025 17589656 1
579 0 000021 32689525 0.1
579 0 000020 17589656 1
581 0 000022 32689525 0.1
583 0 000024 17589656 1
578 11 000023q 32689525 0
578 12 000025a 17589656 0
Actually I have to calculate the incentive for Person. Say in case of above 578. Since It has booked total 4 units out which 3 are with brokers and 1 is individual.
So from broker part his incentive will 2500 INR per unit that is 3*2500 = 7500.
Now comes the discount part. See the points below:
Conditions:
If No discount has been given, than 1% of BSP will be allocated to Incentive to the Sales Person.
If Discount given to booking is between .1% to 1%, than .75% of BSP will be allocated to Incentive to the Sales Person.
If Discount given to booking is between 1 .1% to 2%, than .50% of BSP will be allocated to Incentive to the Sales Person.
If Discount given to booking is between 2% and above, than .25% of
BSP will be allocated to Incentive to the Sales Person.
In the above tables it us clear that 578 has booked 4 units, two with discounts an two without discounts.
So his incentive will be calculated as :
var incentive = total_no_of_units_booked_with_agent * 2500;
// since there might be a possibility that more than one units can be
// booked by a sales person.No we have to find if there is any discount
// applied there, if its there, then extract the incentive for each unit
//and total it using the above condition. For table shown we have
//since it has 4 records
incentive = incentive + (.75% of BSP)+ (.75%of BSP)+(1% of BSP)+(1%of BSP)
For a conditional sum, just use SUM with a CASE statement inside it to enforce your conditions.
SELECT
person,
SUM(CASE WHEN discount = 0.00 THEN 0.0100 * bsp
WHEN discount <= 0.01 THEN 0.0075 * bsp
WHEN discount <= 0.02 THEN 0.0050 * bsp
ELSE 0.0025 * bsp END
+
CASE WHEN agent <> 0 THEN 2500.0
ELSE 0.0 END) AS incentive
FROM
yourTable
GROUP BY
person
I having Following Two Tables and wants the result date and bank wise. The Example is as below.
Table1: Name:- AccountMast
companyID A/CID Name BalDR BalCR
102 14 SHOBHA NULL NULL
102 15 SONKI NULL NULL
102 16 BANK OF INDIA null 12000
Table2 Name :- DeBank
companyID transID date name particulars deposit withdrawal
102 2 12/04/2012 BANK OF INDIA MAHENDRA 1000 NULL
102 4 15/04/2012 CENTRAL BANK MAHENDRA 1000 NULL
102 3 20/05/2012 BANK OF INDIA MAHENDRA 2000 NULL
Result
BANK WISE RESULT BANK OF INDIA
date transID particulars deposit withdrawal BALANCE
01/04/2012 BAL B/F 12000
12/04/2012 2 MAHENDRA 1000 NULL 13000
20/05/2012 3 MAHENDRA 2000 NULL 15000
BANK WISE RESULT CENTRAL BANK OF INDIA
date transID particulars deposit withdrawal BALANCE**
01/04/2012 BAL B/F
15/04/2012 4 MAHENDRA 2000 NULL 2000
So what is the sql statement for it?.