I have a fee table that contains fees in a list of price cutoffs based on item pricing. For example the first fee range is for items that are priced at $0 and up to the next tier have a $1 fee. Items that have a price of $25 up to the next tier have a $2 fee, etc. Here is the fee table:
Fee
Cutoff Fee
------ ---
0 1
25 2
100 3
Here is the item table with the prices:
Item
Id Price
------ ------
1 32
2 18
3 2
4 100
The result should look like this:
Desired Item Fees Result
Id Price Fee Total Price with fee
----- ------- ------- -----------
1 32 2 34
2 18 1 19
3 2 1 3
4 100 3 103
Creating the result has been challenging. Here is what the cartesian product of the join result looks like between the two tables:
Id Price Cutoff Fee
--- ------- ------- ---
1 32 0 1 -- eliminate because price is above the next cut 25
2 18 0 1
3 2 0 1
4 100 0 1 -- eliminate because price is above the next cut 25
1 32 25 2
2 18 25 2 -- eliminate because price is below this cut
3 2 25 2 -- eliminate because price is below this cut
4 100 25 2 -- eliminate because price is above (equal to) the next cut 100
1 32 100 3 -- eliminate because price is below this cut
2 18 100 3 -- eliminate because price is below this cut
3 2 100 3 -- eliminate because price is below this cut
4 100 100 3
the first where is simple:
where price >= cut
this narrows the list down to:
Id Price Cutoff Fee
--- ------- ------- ---
1 32 0 1 -- eliminate because price is above the next cut 25
2 18 0 1
3 2 0 1
4 100 0 1 -- eliminate because price is above the next cut 25
1 32 25 2
4 100 25 2 -- eliminate because price is above (equal to) the next cut 100
4 100 100 3
Here's the question: how do i filter out records that are in the next pricing tier? This is the sql i have so far.
select price, cutoff, fee from item, fee
where price >= cutoff;
I have tried a subquery:
select price, cutoff, fee,
(select min(cutoff), fee from fee where cutoff > price) as nextfee
from item, fee
where price >= cutoff;
but this gives the error:
Operand should contain 1 Column(s)
One way to approach this problem is to use a correlated subquery to get the first fee in the fee table where the cutoff is greater than or equal to the price:
select id, price, fee, (price + fee) as totalprice
from (select id, price,
(select fee
from fee
where price >= cutoff
order by cutoff desc
limit 1
) as fee
from item
) i
What about this? No subjoins, better for performance and simpler.
SELECT i.id, i.price, MAX(f.fee), i.price + MAX(f.fee)
FROM item i INNER JOIN fee f
ON i.price > f.cutoff
GROUP BY i.id, i.price
Related
I have a table below named deposit
dep_id
deposit_amount
comp_id
1
100
1
2
100
1
3
300
2
4
200
2
5
100
2
6
500
3
When I update the table with the query below I get the following table, which is not what I want
UPDATE deposit
SET deposit_amount = (SELECT SUM(deposit_amount) - 50)
WHERE comp_id =1
What the query above does is to subtract 50 from each of the corresponding comp_id
dep_id
deposit_amount
comp_id
1
50
1
2
50
1
3
300
2
4
200
2
5
100
2
6
509
3
But the table below is what I need.
Because seeing the first table and with the query I provided where comp_id =1, we have 100 + 100 = 200, and then 200 - 50 = 150. So because comp_id has 1 IDs two times, therefore we have 75 and 75 because 75 +75 is 150. So we have the table below, which is what I need.
dep_id
deposit_amount
comp_id
1
75
1
2
75
1
3
300
2
4
200
2
5
100
2
6
500
3
The amount supposed to be evenly split amongst the deposits that share a comp_id, even if they weren't before.
Please how do I write the query to suit the table I need? Help!
You can divide the 50 by the count of the records for this id:
UPDATE deposit d1,
(SELECT *, count(*) over (partition by d2.comp_id) as c FROM deposit d2) x
SET d1.deposit_amount = (SELECT SUM(d1.deposit_amount) - 50/x.c)
WHERE d1.comp_id =1
see: DBFIDDLE
ID pcID contractor approver claimed
-------------------------------------------
1 1 one 1000 900
2 1 two 200 100
3 1 three 1000 1000
4 1 six 100 11
5 2 six 100 22
6 3 six 120 1
7 4 three 102 10
From the above table I need to sum the approver amount and claimed amount based on the contractor. Like the below given table. All has been done by using the stored procedure.
ID pcID contractor approver claimed TotalApprover TotalClaimed
--------------------------------------------------------------------------
1 1 one 1000 900 1000 900
2 1 two 200 100 200 100
3 1 three 1000 1000 1000 1000
4 1 six 100 11 100 11
5 2 six 100 22 200 33
6 3 six 120 1 320 34
7 4 three 102 10 1120 1001
Like the above table I need an output adding(sum) in ascending order based on contractor.
Thanks in advance.
You can use window function
select t.*,
sum(approver) over( partition by contractor order by ID) TotalApprover,
sum(claimed) over( partition by contractor order by ID) TotalClaimed,
from table1 t
You want cumulative sums:
select t.*,
sum(approver) over (partition by contractor order by claimid) as totalapprover,
sum(claim) over (partition by contractor order by claimid) as totalclaim
from t;
This is just accumulated the corresponding values by the dimensions you are asking for.
I need to get the total qty available for each franchise based on per item.
I have menu_catalog table which will link to main table of franchise and item table.
id id_franchise id_item
1 1 1
2 1 2
3 1 3
4 2 1
5 2 3
6 3 2
Each of the franchise might contain different items.
For the stock_transaction table
id id_franchise id_item stock_in stock_out type unit_price
1 1 1 10 1 5.00
2 1 1 2 2 5.00
3 2 3 10 1 3.00
// type : 1 = stock in while 2 = stock out
Expected output :
id_item franchise1 franchise2 franchise3
1 8,40 0,0 0,0
2 0,0 0,0 0,0
3 0,0 10,30 0,0
I have a condition, when type = 1 then SUM the stock_in else SUM stock_out * -1, same for the price. I will store the total qty and total price for each item based on franchise.
I will select all item belong to this 3 franchises, even some item not existed on their menu catalog. The item not belong to the franchise will be return as 0.
p.s. the column of franchise is not fixed, will based on the id_franchise passed into the query.
How can i do this?
Fiddler Here: http://sqlfiddle.com/#!9/9579da/3
Given this table of products
CountryId Product Quantity
1 Apple 100
1 Banana 5000
2 Carrot 50000
3 Apple 500
4 Apple 250
6 Apple 6000
And this table of available money
CountryId Quantity Rate
1 4135 0.005
1 870.5 1
1 1000 1
2 7249.71 0.007
2 1788 0.01
2 10 1
2 352 10
3 1900 0.09
4 29877 0.005
5 7108 0.005
Where Rate represents an exchange rate for the country. Not shown in the money table are seller Ids.
So for the first product, There are 100 apples in country 1. The Pricing for those Apples would be 100 * (0.005) because there was 4135 available money units for the 0.005 rate, of which we only needed 100 for our apples.
Another example: There are 5000 bananas for country 1. The pricing of those Bananas would be 4135 * (0.005) + 865 * (1). There wasn't enough 4135 money units at rate 0.005 so it had to take 865 units from the next available rate which was 1.
I am trying to use this logic and join the money table onto the products table and have a Price column. I have no idea how to start because it is not a simple Join
I have 4 major tables in my database.
Season --> seasonID
Trials --> trialID
Competition --> CID,name
Camps --> campID,DivisionID(FK)
Divisions ---> DivisionID
Contestants --->ContestantID
Now a contestant belongs to / are members of a divisions.
Then a division belongs to a camp.
All this leads to my Performance table.
PERFORMANCE TABLE
SeasonID|TrialID|CampID|DivID|CompetionID|CtestantID|Score1 |Score2 |Total
1 1 1 1 1 1 20 20 40
1 1 1 1 2 1 20 15 30
1 2 1 1 1 2 10 5 15
1 2 1 1 2 2 5 5 10
1 2 1 1 1 1 10 30 40
1 2 1 1 2 1 20 10 30
How can I query this performance table to give me the competition name, total score and rank (ranking over total score) of each contestant in each competition by trials and by seasons?
Example:
In season 1 and trial 2 I want to have:
SeasonID| TrialID | ContestantID| Competition | TotalScore | Rank
1 2 1 1 40 1
1 2 2 1 15 2
1 2 1 2 30 1
1 2 2 2 10 2
How do I go about this? I have tried table variables, pivot and joins but I can only rank by competitions, but I don't how to aggregate the results to get the result above!
I'm not exactly sure how you calculated your desired results. I think this is what you are after but, if so, the TotalScore in the desired results of your question should be 10 for the last record, not 20.
SELECT SeasonID, TrialID, ContestantID, CompetitionID, Total,
DENSE_RANK() OVER(PARTITION BY CompetitionId ORDER BY Total DESC) AS [Rank]
FROM PerformanceTable