Moving Median PostgreSQL with Partition - sql

I'm looking to create a prior rolling 4 quarter Median. Some entries have less than 4 quarters, some have more. I want this by Employee. Needs to account for different tenure for different employees.
Result for 2021-1 should represent the prior 4 quarters median (and not account for current quarter).
I was able to figure out a rolling average with partitioning but not sure how to tackle a rolling median.
Thanks!
Employee ID
Quarter
Sales
EXPECTED RESULT
A
2020-1
1000
NULL
A
2020-2
2000
1000
A
2020-3
3000
1500
A
2020-4
4000
2000
A
2021-1
5000
2500
A
2021-2
4000
3500
B
2020-3
8000
NULL
B
2020-4
7000
8000
B
2021-1
6000
7500
B
2021-2
5000
7000
B
2021-3
1000
6500
C
2021-1
5000
NULL
C
2021-2
0
5000
C
2021-3
4000
2500

Related

Cumulative over table rows with condition Oracle PL/SQL

I have two tables:
Employees:
employee_id field max_amount
3 a 3000
4 a 3000
1 a 1600
2 a 500
4 b 4000
2 b 4000
3 b 1700
ordered by employee, field, amount desc.
Amounts (pol, premia,field):
pol premia field **assign_to_employee**
11 900 a 3
44 1000 a 3
55 1400 a 4
77 500 a 3
88 1300 a 1
22 800 b 4
33 3900 b 2
66 1300 b 4
Assign Stats Table:
employee_id field max_amount true_amount remain
3 a 3000 2400 600
4 a 3000 1400 1600
1 a 1600 1300 300
2 a 500 0 500
4 b 4000 2100 1900
2 b 4000 3900 100
3 b 1700 0 1700
The output : assign_to_employee field (merged to amounts table).
Algoritem wise : The method is to assign pol's to employees until the premia needs to be added to the cumulative_sum is bigger then the max amount per employee listed in the employees table. You always start with the employess with most max amount until you cannot add any other pols to the employee.
I start with the employees with the grater max_amount per field.
I keep doing this until no pols remains to be assign.
Can you help me solve this?
Thank you.

SQL. Split data over month based on expected hours

I really hope you can help me with this problem, which seems pretty complicated for me.
Dealid: DealprojectStartDate: expectedhours:
3534 2021-01-01 200
What I want is to split the weightamount out on different month in the future based on the expected number of hours.
I have following distribution key for expected hours:
0-500 = 2 month
500-1500 = 4 month
1500 - 4000 = 6 month
4000 - above = 8 month.
So forexample: in the above observation the start date is 01/01 and expected hours of 100 therefore weightamount should be split over 2 month -> Month 1 = 100 and Month 2 = 100.
Important note: If it is the first of the month then it should be allocated to that month. So for the above exapmle because it is the first of the monst (01/05) then it should be allocated to month 5 and 6, but if the start date wat 07/05 then i should have been allocated to month 6 and 7.
What i think would work if to get a new tabel that would split above observation into this:
Dealid: allocation date: expectedhours:
3534 2021-01-01(jan) 100
3534 2021-02-01(feb) 100
Hope you guy can help. Thanks
Consider the following table:
min max count month_number
0 500 2 1
0 500 2 2
500 1500 4 1
500 1500 4 2
500 1500 4 3
500 1500 4 4
1500 4000 6 1
1500 4000 6 2
1500 4000 6 3
1500 4000 6 4
1500 4000 6 5
1500 4000 6 6
4000 1000000000 8 1
4000 1000000000 8 2
4000 1000000000 8 3
4000 1000000000 8 4
4000 1000000000 8 5
4000 1000000000 8 6
4000 1000000000 8 7
4000 1000000000 8 8
If we call that table calc_lookup and your table atable then this query will give you the results you want
SELECT a.Dealid,
dateadd(month, dealprojectstartdate, l.month_number-1) as alocation_date,
a.expectedhours / l.count as expectedhours
FROM atable a
JOIN calc_lookup l on a.expectedhours between l.min and l.max
You don't give detail of the edge cases and such -- so there may be some changes needed (off by one, rounding, etc.)

show employees' salary history by adding StartingSalary and Increase values Access

On a form, I have a chart that shows the Increase History of each employee (What rating they were given each year, and how much of an increase they got)
I can't post an image since I have less than 10 reputation, but I hope it's clear.
What I need is a similar graph, but for the history of each employee's salary. I have a StartingSalary field in IncreaseEmployeesQ, and an Increase field. It's complicated, all I've managed to do is this:
SELECT IncreaseEmployeesQ.LocalID, Sum([Increase]+[StartingSalary]) AS CurrentSalary
FROM IncreaseEmployeesQ
GROUP BY IncreaseEmployeesQ.LocalID;
But what this does is add the StartingSalary each time, since it's repeated in each year. and it gives me one value for each employee, instead of one value for each year so I can have a chart that tracks the progress of the employee's salary.
I tried going to the original IncreaesT instead of the query that has it and EmployeesT (IncreaseEmployeesQ), thinking maybe I can have a calculated field if I add a StartingSalary field in IncreaseT (It's originally in EmployeesT) and then link it in relationships and enforce referential integrity, but I kept getting an error message. After some research I gathered that the reason is because the two tables have different Primary keys, so I resorted to the Query.
Is the chart I'm aiming to get to even possible? a chart that shows how each employee's salary has been progressing since 2010? (that's as far back as my data goes)
-assuming that a query is the right way to get this done- The query I'm working on looks like this:
LocalID Increase Years StartingSalary
1 1000 2013 7000
1 500 2014 7000
1 0 2015 7000
1 500 2016 7000
2 0 2013 5000
2 500 2014 5000
2 500 2015 5000
2 0 2016 5000
What I want it to look like (so I make a chart later) is this:
LocalID Increase Years StartingSalary CurrentSalary
1 1000 2013 7000 8000
1 500 2014 7000 8500
1 0 2015 7000 8500
1 500 2016 7000 9000
2 0 2013 5000 5000
2 500 2014 5000 5500
2 500 2015 5000 6000
2 0 2016 5000 6000
If it turns out like this, I can make a chart that has the Years and the CurrentSalary for each employee.
But all I've managed to do is the code above, which gives me this result
LocalID Increase Years StartingSalary CurrentSalary
1 1000 2013 7000 30000
1 500 2014 7000 30000
1 0 2015 7000 30000
1 500 2016 7000 30000
2 0 2013 5000 21000
2 500 2014 5000 21000
2 500 2015 5000 21000
2 0 2016 5000 21000
I hope everything is clear now
You want a cumulative sum. One way to do this in MS Access uses a correlated subquery:
SELECT ieq.*,
(ieq.StartingSalary +
(SELECT SUM(increase)
FROM IncreaseEmployeesQ as ieq2
WHERE ieq2.LocalID = ieq.LocalId AND ieq2.Years <= ieq.Years
)
) as CurrentSalary
FROM IncreaseEmployeesQ as ieq

DAX / PP Aggregate a variable project margin down a column

I need a solution similar to this:
DAX running total (or count) across 2 groups
However slightly more complex.
I have the following:
(apologies for the layout - i can't post pictures)
Name Date Monthly Rev Total Rev Margin( % Rev)
Proj 1 1/08/2014 0 7000 15%
Proj 1 1/09/2014 1000 7000 15%
Proj 1 1/10/2014 1000 7000 15%
Proj 1 1/11/2014 1000 7000 15%
Proj 1 1/12/2014 0 7000 15%
Proj 1 1/01/2015 0 7000 15%
Proj 1 1/02/2015 2000 7000 15%
Proj 1 1/03/2015 2000 7000 15%
Proj 2 1/11/2014 0 16000 10%
Proj 2 1/12/2014 1500 16000 10%
Proj 2 2/12/2014 1500 16000 10%
Proj 2 3/12/2014 1500 16000 10%
Proj 2 4/12/2014 1500 16000 10%
Proj 2 5/12/2014 2000 16000 10%
Proj 2 6/12/2014 2000 16000 10%
Proj 2 7/12/2014 0 16000 10%
Proj 2 8/12/2014 2000 16000 10%
Proj 2 9/12/2014 2000 16000 10%
Proj 2 10/12/2014 2000 16000 10%
Monthly rev is the revenue received in a month, total is the total project value and margin is the percentage of revenue. The table is linked to a dates table by Date.
I need to show margin by date (there are other descriptive columns in the table for slicing) however the margin calc is not straightforward.
In an excel table it would look something like this:
Cumm simple margin | Completion| Cumm complex margin | Margin earnt
0 0% 0 0
150 20% 30 30
300 40% 120 90
450 60% 270 150
450 60% 270 0
450 60% 270 0
750 80% 600 330
1050 100% 1050 450
0 0% 0 0
150 11% 17 17
300 22% 67 50
450 33% 150 83
600 44% 267 117
800 56% 444 178
1000 67% 667 222
1000 67% 667 0
1200 78% 933 267
1400 89% 1244 311
1600 100% 1600 356
Where:
Simple margin is calculated on a cumulative basis as % of monthly Rev
Percentage complete of the project is calculated based on "active" months where revenue is earned
Cumulative simple margin is multiplied by the % complete
Actual margin earned in a particular month is the difference between two months.
Note that Monthly revenue is not necessarily continuous.
No idea how to recreate this in power pivot, any suggestions would be well received.
Cheers
Assuming
That your Project 2 data should run monthly from 1/11/2015 to 1/09/2015 (rather than individual December dates)
You have your data in a table called 'ProjectMargins'
Your DateDim table is called 'Reporting Dates'
Then these are the DAX Measures you need (although there may be simpler methods for achieving these results):
[MonthlyRev]:=SUM(ProjectMargins[Monthly Rev])
[ActiveMonth]:=CALCULATE(COUNTROWS('ProjectMargins'),FILTER('ProjectMargins',[MonthlyRev]>0))
[AllActiveMonths]:=CALCULATE([ActiveMonth],ALL('Reporting Dates'[Date]))
[Completion]:=DIVIDE(CALCULATE([ActiveMonth],FILTER(ALL('Reporting Dates'[Date]),'Reporting Dates'[Date] <= MAX(ProjectMargins[Date]))),[AllActiveMonths])
If you need to calculate TotalRev, from your Monthly Rev, Rather than it appearing in the original source table:
[TotalRev]:=IF(ISBLANK(MAX(ProjectMargins[Margin( % Rev)])),BLANK(),CALCULATE([MonthlyRev],ALL('Reporting Dates'[Date])))
[Rev%]:=MAX(ProjectMargins[Margin( % Rev)])
[Cumm Simple Margin]:=CALCULATE([MonthlyRev]*[Rev%],FILTER(ALL('Reporting Dates'[Date]),'Reporting Dates'[Date] <= MAX(ProjectMargins[Date])))
[Cumm Complex Margin]:=[Completion]*[Cumm Simple Margin]
[Previous Month Cumm Complex]:=CALCULATE([Cumm Complex Margin], DATEADD('Reporting Dates'[Date],-1,MONTH))
[Margin Earnt]:=IF([Cumm Complex Margin]>0,[Cumm Complex Margin]-[Previous Month Cumm Complex],BLANK())
NOTE: This assumes that the margin is never negative.
Ensure that the date field from the DateDim table is used in your pivot, not the date field from the Fact table.

Sum values from Duplicated rows

There's my sql data:
code name total
---------------
3 Sprite 2400
17 Coke 1500
6 Dew 1000
17 Coke 3000
6 Dew 2000
But code and name has duplicated values and I want to sum total from each duplicated field.
Something like this:
code name total
---------------
3 Sprite 2400
17 Coke 4500
6 Dew 3000
How could I do that in sql?
SELECT code, name, sum(total) AS total FROM table GROUP BY code, name