Calculate sum in tier pricing. SQL Server. Tier pricing table - sql

I am having trouble with my sum query in SQL Server.
I have a tier price table set up like. The name of the table is called TierPricing.
CID RangeID MinValue MaxValue Price Class
1 1 1 5 1.50 1
2 2 6 10 1.25 1
3 3 11 999999999 1.00 1
.
I have a query of
DECLARE #QuantityEntered int
DECLARE #ClassEntered int
SET #QuantityEntered = 10;
SET #ClassEntered = 1
SELECT IIf(#QuantityEntered>=TierPricing.MaxValue,TierPricing.MaxValue*TierPricing.Price,(#QuantityEntered-(TierPricing.MinValue-1))*TierPricing.Price)) AS RangePrice
FROM
TierPricing
WHERE
(((TierPricing.MinValue)<=#QuantityEntered) AND ((TierPricing.Class)=#ClassEntered));
The problem arises when I use the value of 10 for #QuantityEntered. Instead of returning 13.75 it returns 20.00 and I cant figure out why. From the table from value 9 to 10 should increase by 1.25 from 12.50 to 13.75.
Further Explanation.
#QuantityEntered = 1 returns 1.50 because 1 falls in between 1 and 5 and 1.50 is added from price field for a total of 1.50
#QuantityEntered = 2 returns 3.00 because 2 falls in between 1 and 5 and 1.50 is added from price field for total of 3.00
#QuantityEntered = 3 returns 4.50 because 3 falls in between 1 and 5 and 1.50 is from price field added for total of 4.50
#QuantityEntered = 4 returns 6.00 because 4 falls in between 1 and 5 and 1.50 is from price field added for total of 6.00
#QuantityEntered = 5 returns 7.50 because 5 falls in between 1 and 5 and 1.50 is from price field added for total of 7.50
#QuantityEntered = 6 returns 8.75 because 6 falls in between 6 and 10 and 1.25 is from price field added for total of 8.75
#QuantityEntered = 7 returns 10.00 because 7 falls in between 6 and 10 and 1.25 is from price field added for total of 10.00
#QuantityEntered = 8 returns 11.25 because 8 falls in between 6 and 10 and 1.25 is from price field added for total of 11.25
#QuantityEntered = 9 returns 12.50 because 9 falls in between 6 and 10 and 1.25 is from price field added for total of 12.50
#QuantityEntered = 10 Should return 13.75 but returns 20.00
What I am doing wrong with my query?

I was trying to solve this problem myself when I found your question. I figured out a set based way to get the correct result, but you have to change your Min and Max values to start from 0 and start from the lower tier's end. So the tiers are now 0-5, 5-10, and 10 - 999999999. Here is a recreation of your problem:
create table #TierPricing
(
CID int
,RangeId int
,MinValue int
,MaxValue int
,Price money
,Class int
)
insert into #TierPricing(CID, RangeId, MinValue, MaxValue, Price, Class) values (1,1,0,5,1.50,1)
insert into #TierPricing(CID, RangeId, MinValue, MaxValue, Price, Class) values (2,2,5,10,1.25,1)
insert into #TierPricing(CID, RangeId, MinValue, MaxValue, Price, Class) values (3,3,10,999999999,1.00,1)
DECLARE #QuantityEntered int
DECLARE #ClassEntered int
SET #QuantityEntered = 10;
SET #ClassEntered = 1
;with t as (
select
#TierPricing.*
,case
when #QuantityEntered > MaxValue then MaxValue - MinValue --The #QuantityEntered fills up the entire tier
when #QuantityEntered > MinValue then #QuantityEntered - MinValue --The #QuantityEntered partillay fills the tier
else 0
end as TierQuantity
from #TierPricing
)
select
sum(TierQuantity * Price) as RangePrice
from t
drop table #TierPricing
This will return 13.75 when #QuantityEntered is set to 10.

Related

SQL Running total use case

I have a below dataframe from which i need the dates when sum of the qty for that particular id hits x% from the total sum then i need to populate that date against the id. Can someone please help me with the sql query for this
Table A
ID QTY
1 10
2 20
3 30
4 40
---
Table B
ID DATE qty
1 01-01-2020 1
1 01-02-2020 2
1 01-03-2020 4
1 01-04-2020 3
The expected output is for ID1 it is 01-03-2020 date the sum of qty exceed 60% (1+2+4 > 60% of total qty 10) of the QTY in table A
Expected output
ID date_where_qty_>60%
1 01-03-2020

How to write the query to make report by month in sql

I have the receiving and sending data for whole year. so i want to built the monthly report base on that data with the rule is Fisrt in first out. It means is the first receiving will be sent out first ...
DECLARE #ReceivingTbl AS TABLE(Id INT,ProId int, RecQty INT,ReceivingDate DateTime)
INSERT INTO #ReceivingTbl
VALUES (1,1001,210,'2019-03-12'),
(2,1001,315,'2019-06-15'),
(3,2001,500,'2019-04-01'),
(4,2001,10,'2019-06-15'),
(5,1001,105,'2019-07-10')
DECLARE #SendTbl AS TABLE(Id INT,ProId int, SentQty INT,SendMonth int)
INSERT INTO #SendTbl
VALUES (1,1001,50,3),
(2,1001,100,4),
(3,1001,80,5),
(4,1001,80,6),
(5,2001,200,6)
SELECT * FROM #ReceivingTbl ORDER BY ProId,ReceivingDate
SELECT * FROM #SendTbl ORDER BY ProId,SendMonth
Id ProId RecQty ReceivingDate
1 1001 210 2019-03-12
2 1001 315 2019-06-15
5 1001 105 2019-07-10
3 2001 500 2019-04-01
4 2001 10 2019-06-15
Id ProId SentQty SendMonth
1 1001 50 3
2 1001 100 4
3 1001 80 5
4 1001 80 6
5 2001 200 6
--- And the below is what i want:
Id ProId RecQty ReceivingDate ... Mar Apr May Jun
1 1001 210 2019-03-12 ... 50 100 60 0
2 1001 315 2019-06-15 ... 0 0 20 80
5 1001 105 2019-07-10 ... 0 0 0 0
3 2001 500 2019-04-01 ... 0 0 0 200
4 2001 10 2019-06-15 ... 0 0 0 0
Thanks!
Your question is not clear to me.
If you want to purely use the FIFO approach, therefore ignore any data the table contains, you necessarely need to order by ID, which in your example you are providing, and looks like it is in order of insert.
The first line inserted should be also the first line appearing in the select (FIFO), in order to do so you have to use:
ORDER BY Id ASC
Which will place the lower value of the ID first (1, 2, 3, ...)
To me though, this doesn't make much sense, so pay attention to the meaning o the data you actually have and leverage dates like ReceivingDate, and order by that, maybe even filtering by month of the date, below an example for January data:
WHERE MONTH(ReceivingDate) = 1

Issue with Oracle select query 2

I have a table report of production, and I want to bridge between minus value and positive value on QTY field.
I want to make a new column with positive value, and another column with negative value selected from the QTY field.
mtl_trx qty uom
1 20 1230 KG
2 39 950 KG
3 45 100 LBR
4 91 250 KG
5 118 -500 KG
6 125 -284 KG
7 137 -120 KG
8 143 -80 KG
If I understand correctly, you want to select two columns, one showing the positiv values, one the negative ones? Use a case construct to decide whether to show a value or not.
select mtl_trx, qty, uom,
case when qty > 0 then qty end as qty_pos,
case when qty < 0 then qty end as qty_neg
from mytable;
select mtl_trx, qty, uom,
case when qty > 0 then qty else 0 end as positive,
case when qty < 0 then qty else 0 end as negative
from production;

SQL - Column per week (X weeks from declared start date) [duplicate]

This question already has an answer here:
SQL Server: Dynamic pivot with headers to include column name and date
(1 answer)
Closed 8 years ago.
I need to run a select statement that returns a number of invoices with their values showing in a column that's appropriate to the week that the invoice appeared in. Example:
id value invoiced
1 150 2014-01-06
2 220 2014-01-13
3 190 2014-01-13
4 880 2014-01-27
5 325 2014-02-03
I would need this data to display in a format similar to below:
ID W/E 2014-01-05 W/E 2014-01-12 W/E 2014-01-19 W/E 2014-01-26 W/E 2014-02-02 W/E 2014-02-09 W/E 2014-02-16
1 0 150 0 0 0 0 0
2 0 0 220 0 0 0 0
3 0 0 190 0 0 0 0
4 0 0 0 0 880 0 0
5 0 0 0 0 0 325 0
With the first date being taken from a variable and the remaining weeks being calculated from that point on (for X weeks). My initial thought is to use a temporary table to hold rows for each of the date ranges and then join that table to perform a pivot... but to be honest this is all pretty new to me so I have absolutely no idea of the syntax.
There is no requirement for any grouping (no sums to deal with), I just need to make sure that the appropriate values end up in the appropriate columns.
p.s. I know I could do this with loops on the presentation layer, but in this particular case, there isn't one as such.
declare #t table (Id INT,Value INT,invoiced Date )
insert into #t (Id,Value,invoiced)values (1,150,'2014-01-06')
insert into #t (Id,Value,invoiced)values (2,220,'2014-01-13')
insert into #t (Id,Value,invoiced)values (3,190,'2014-01-15')
insert into #t (Id,Value,invoiced)values (4,880,'2014-01-27')
insert into #t (Id,Value,invoiced)values (5,325,'2014-01-29')
Select id,
[w/e2014-01-06],
[w/e2014-01-13],
[w/e2014-01-15],
[w/e2014-01-27],
[w/e2014-01-29]
from
(Select distinct t.ID,t.Value,
'w/e' + CAST(t.invoiced AS VARCHAR)AS Dateno
from #t t)t
PIVOT (MAX(value)FOR Dateno IN([w/e2014-01-06],[w/e2014-01-13],[w/e2014-01-15],[w/e2014-01-27],[w/e2014-01-29]))p

sql Query on effective date

I would like to get report for drink purchased in whole month but price of the drink can change any time in month and I would like to get report for a month with price change
I have two tables
SELECT [ID]
,[DrinkID]
,[UserID]
,[qty]
,[DateTaken]
FROM [Snacks].[dbo].[DrinkHistory]
SELECT [ID]
,[DrinkID]
,[UserID]
,[qty]
,[DateTaken]
FROM [Snacks].[dbo].[DrinkHistory]
[DrinkHistory]:
ID DrinkID UserID qty DateTaken
----------------------------------------------------------------------
1 1 1 1 2014-05-10
2 1 1 2 2014-05-15
3 2 1 1 2014-06-01
4 2 1 4 2014-06-01
5 1 1 3 2014-05-20
6 1 1 4 2014-05-30
[DrinkPricesEffect]:
PriceID DrinkID DrinkPrice PriceEffectiveDate IsCurrent
-----------------------------------------------------------------------------------
1 1 10.00 2014-05-01 1
2 1 20.00 2014-05-20 1
3 2 9.00 2014-06-01 1
4 2 8.00 2014-01-01 1
5 1 30.00 2014-05-25 1
6 1 40.00 2014-05-28 1
I would like to have result as under date taken between 2014-05-1 to 2014-05-31
DrinkId Qty Price DateTaken PriceEffectiveDate
-----------------------------------------------------------------------
1 1 10 2014-05-10 2014-05-01
1 2 10 2014-05-15 2014-05-01
1 3 20 2014-05-20 2014-05-20
1 4 40 2014-05-30 2014-05-28
Is there any who can give me some idea or write query for me?
If your drink price can change any time in a month you could additionaly save the price for each purchase. I would add a column [PricePaid] to the table [DrinkHistory].
When adding a record to [DrinkHistory], the price for the drink at the moment is known, but later it might change so you save the current price to the history...
Then for your result you could just display the Whole [DrinkHistory]
SELECT * FROM DrinkHistory;
This should work:
Select
DH.DrinkId,
DH.Qty,
DPE.DrinkPrice AS Price,
DH.DateTaken,
DPE.PriceEffectiveDate
FROM DrinkHistory DH
JOIN DrinkPricesEffect DPE ON DPE.PriceID =
(
Select Top 1 PriceID FROM
(
Select PriceID,RANK() OVER(ORDER BY PriceEffectiveDate DESC ) AS rnk
FROM DrinkPricesEffect
WHERE DH.DrinkId = DrinkId AND
DH.DateTaken >= PriceEffectiveDate
)SubQ WHERE rnk = 1
)
WHERE DH.DateTaken Between '2014-05-01' AND '2014-05-30'
Here you can find the SQL Fiddle link: http://sqlfiddle.com/#!6/5f8fb/26/0