Aggregate one measure by another in MS Analysis Services - ssas

There is a CUBE with two measures Prices, Volumes and dimension Hours. (The real CUBE is much complex, this is a simplified version.)
Hours Prices Volumes
0 0 100
0 10 20
0 20 300
0 40 100
0 50 50
1 0 500
1 20 50
1 25 200
1 40 30
1 50 10
How to aggregate Volumes by Prices and get next result (probably by using MDX query):
Prices Volumes
0 600
10 20
20 350
25 200
40 130
50 60

Related

How can I write pyspark code to get below output

Input:
Buy-A
Date
Time
Qty
Per Share price
Total Value
15
10
10
10
100
15
14
20
10
200
Sell - B
Date
Time
Qty
Per Share price
Total Value
15
15
15
20
300
Output:
Date
Buy Time
Buy Qty
Buy Per Share price
Buy Total Value
Sell Qty
Sell Per Share Price
Sell Total Value
15
10
10
10
100
10
20
200
15
14
5
10
50
5
20
100
15
14
15
10
150
By using pyspark

How can I transfer the data from on column to another based on another column values in SQL

select Products, Fiscal_year, Fiscal_Period, Stock_QTY, DaysRemaining,
(Stock_QTY / DaysRemaining) as QtyforPeriod,
Stock_QTY -(Stock_QTY / DaysRemaining) as LeftforNextmonth
from Stocks
products| Fiscal_yaer| Fiscal_period| Stock_QTY |DaysReamain| QtyforPeriod |LeftforNextMonth
5000 22 1 100 4
6000 22 1 200 4
7000 22 2 300 20
7000 22 3 400 40
8000 23 1 500 60
5000 23 1 600 60
7000 23 2 700 90
8000 23 3 800 100
There is any possibility to write a query if the Fiscal_yae =22 Fiscal_period=4. Subtract StockTY - LeftforNextMonth of period 3 and divided by DaysRemaining.
Like if the Fiscal_yae =22 Fiscal_period=5. Subtract StockTY - LeftforNextMonth of period 4 and divided by days remaining.
Like if the Fiscal_yae =22 Fiscal_period=6. Subtract StockTY ( - ) LeftforNextMonth of period 5 and divided by days remaining.

Properly 'Joining' two Cross Applies

I've got a query with three Cross-Applies that gather data from three different tables. The first Cr-Ap assists the 2nd and 3rd Cr-Ap's. It finds the most recent ID of a certain refill for a 'cartridge', the higher the ID the more recent the refill.
The second and third Cr-Ap's gather the SUMS of items that have been refilled and items that have been dispensed under the most recent Refill.
If I run the query for Cr-Ap 2 or 3 separately the output would look something like:
ID Amount
1 100
2 1000
3 100
4 0
5 0
etc
Amount would be either the amount of dispensed or refilled items.
Only I don't want to run these queries separately, I want them next to each other.
So what I want is a table that looks like this:
ID Refill Dispense
1 100 1
2 1000 5
3 100 7
4 0 99
5 0 3
etc
My gut tells me to do
INNER JOIN crossaply2 ON crossapply3.ID = crossapply2.ID
But this doesn't work. I'm still new to SQL so I don't exactly know what I can and can't join, what I do know is that you can use crossapply as a join (sorta?). I think that might be what I need to do here, I just don't know how.
But that's not it, there's another complication, there are certain refills where nothing gets dispensed. In these scenarios the crossapply I wrote for dispenses won't return anything for that refillID. With nothing I don't mean NULL, I mean it just skips the refillID. But I'd like to see a 0 in those cases. Because it just skips over those ID's I can't get COALESCE or ISNULL to work, this might also complicate the joining of these two applies. Because an INNER JOIN would skip any line where there is no Dispensed amount, even though there is a Refilled amount Id like to see.
Here is my code:
-- Dispensed SUM and Refilled SUM combined
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id]
,Refills.Refilled
,Dispenses.Dispensed
FROM [CartridgeRefill]
CROSS APPLY(
SELECT MAX([CartridgeRefill].[Id]) AS RecentRefillID
FROM [CartridgeRefill]
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS RecentRefill
CROSS APPLY(
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id] AS RefilledID
,SUM([CartridgeRefillMedication].[Amount]) AS Refilled
FROM [CartridgeRefillMedication]
INNER JOIN [CartridgeRefill] ON [CartridgeRefillMedication].[FK_CartridgeRefill_Id] = [CartridgeRefill].[Id]
WHERE [CartridgeRefillMedication].[FK_CartridgeRefill_Id] = RecentRefill.RecentRefillID
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS Refills
CROSS APPLY(
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id] AS DispensedID
,SUM([CartridgeDispenseAttempt].[Amount]) AS Dispensed
FROM [CartridgeDispenseAttempt]
INNER JOIN [CartridgeRefill] ON [CartridgeDispenseAttempt].[FK_CartridgeRefill_Id] = [CartridgeRefill].[Id]
WHERE [CartridgeDispenseAttempt].[FK_CartridgeRefill_Id] = RecentRefill.RecentRefillID
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS Dispenses
GO
The output of this code is as follows:
1 300 1
1 300 1
1 200 194
1 200 194
1 200 8
1 200 8
1 0 39
1 0 39
1 100 14
1 100 14
1 200 1
1 200 1
1 0 28
1 0 28
1 1000 102
1 1000 102
1 1000 557
1 1000 557
1 2000 92
1 2000 92
1 100 75
1 100 75
1 100 100
1 100 100
1 100 51
1 100 51
1 600 28
1 600 28
1 200 47
1 200 47
1 200 152
1 200 152
1 234 26
1 234 26
1 0 227
1 0 227
1 10 6
1 10 6
1 300 86
1 300 86
1 0 194
1 0 194
1 500 18
1 500 18
1 1000 51
1 1000 51
1 1000 56
1 1000 56
1 500 48
1 500 48
1 0 10
1 0 10
1 1500 111
1 1500 111
1 56 79
1 56 79
1 100 6
1 100 6
1 44 134
1 44 134
1 1000 488
1 1000 488
1 100 32
1 100 32
1 100 178
1 100 178
1 500 672
1 500 672
1 200 26
1 200 26
1 500 373
1 500 373
1 100 10
1 100 10
1 900 28
1 900 28
2 900 28
2 900 28
2 900 28
etc
It is total nonsense that I can't do much with, it goes on for about 20k lines and goes through all the ID's, eventually.
Any help is more than appreciated :)
Looks like overcomplicated a bit.
Try
WITH cr AS (
SELECT [FK_CartridgeRegistration_Id]
,MAX([CartridgeRefill].[Id]) RecentRefillID
FROM [CartridgeRefill]
GROUP BY [FK_CartridgeRegistration_Id]
)
SELECT cr.[FK_CartridgeRegistration_Id], Refills.Refilled, Dispenses.Dispensed
FROM cr
CROSS APPLY(
SELECT SUM(crm.[Amount]) AS Refilled
FROM [CartridgeRefillMedication] crm
WHERE crm.[FK_CartridgeRefill_Id] = cr.RecentRefillID
) AS Refills
CROSS APPLY(
SELECT SUM(cda.[Amount]) AS Dispensed
FROM [CartridgeDispenseAttempt] cda
WHERE cda.[FK_CartridgeRefill_Id] = cr.RecentRefillID
) AS Dispenses;

Calculate fixed Cost/day for multiple services on same date

Desired Output table T with Calculated Cost column:
SvcID Code ID Date Mins Units Cost
1 3000 15 4/4/2016 60 10 70
2 3000 17 4/4/2016 45 10 0
3 3000 15 5/2/2016 30 10 70
4 3000 18 5/2/2016 60 10 0
5 3000 10 5/2/2016 30 10 0
6 4200 16 2/1/2016 60 4 60
7 4200 9 2/1/2016 30 2 30
Query for calculating and displaying:
SELECT
...
,CASE
WHEN Code=4200 THEN Units*15
WHEN Code=3000 THEN ?
END AS Cost
FROM ...
WHERE Code IN ('3000','4200')
GROUP BY ....;
Cost should be a total of 70 for all services offered on same date for Code 3000, irrespective of number of services offered. No relation between Minutes and Units for this Code for calculating Cost.
One way could be to calculate cost as 70 for any one service and make the remaining services cost 0 for same date. Can this be done in the CASE statement?
Any better way to achieve this?
You need to Investigate Window functions MSDN.
Your case would become something like this:
-- New select statament
SELECT
...
,CASE
WHEN Code=4200 THEN Units*15
WHEN Code=3000 THEN ( CASE WHEN DuplicateNum = 1 THEN 70 ELSE 0 END )?
END AS Cost
FROM(
-- Your current query (with case statement removed) and ROW_NUMBER() function added
SELECT
..., ROW_NUMBER() OVER( PARTITION BY Code, Date ORDER BY ID ) AS DuplicateNum
FROM ...
WHERE Code IN ('3000','4200')
GROUP BY ....
) AS YourCurrentQuery;

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.