AWS QuickSight: maxOver() calculated field? - sql

I am a stock trader who visualizes data in QuickSight. I identify the trades I want to submit to the market, sometimes for the same stock, at the same time, but in opposite directions depending on the price of the stock at that time. See below for an example of trades I might identify for 1/19/22 0800:
Date
Hour
Stock
Direction
Price
Volume
1/19/22
0800
Apple
BUY
$10
2
1/19/22
0800
Apple
SELL
$20
1
1/19/22
0800
Microsoft
BUY
$15
3
Using QuickSight, I want to visualize (in pivot tables and charts) the volume that I trade, using the maximum possible trade volume. For example, QuickSight simply sums the Volume column to 6, when really I want it to sum to 5, because the max possible trade volume for that hour is 5 (the Apple trades in the example are mutually exclusive, because the stock price cannot be both beneath $10, triggering a BUY, and above $20, triggering a SELL at the same date-time. Therefore, I want the day's traded volume to reflect the MAX possible volume I could have traded (2+3)).
I have used the maxOver() function as so: maxOver({volume}, [{stock}, {date}, {hour}], PRE_AGG), but I would like to view my trade volume rolled up to the day as so:
Date
Volume
1/19
5
Is there a way to do this using QuickSight calculated fields? Should this aggregation be done with a SQL custom field?

Add a new calculated field called
volume_direction_specifier
{Volume} * 10 + ifelse({Direction}='BUY', 1, 2)
This is a single number that will indicate the direction and volume. (this is needed in cases where the max possible volume is the same for both the BUY and SELL entries within the same hour).
Then compute the maxOver on this new field in a calculated field called max_volume_direction_specifier
maxOver({volume_direction_specifier}, [{stock}, {date}, {hour}], PRE_AGG)
Add a new field which will give the Volume for rows that have the max volume_direction_specifier per hour
volume_for_max_trade_volume_per_hour
ifelse(volume_direction_specifier = max_volume_direction_specifier, {volume}, null)
And finally, you should be able to add volume_for_max_trade_volume_per_hour to your table (grouped by day) and its SUM will give the maximum possible trade volume per day.

Related

Rolling Balances with Allocated Transactions

I am needing to Calculate the start/end Balances by day for each Site/Department.
I have a source table call it “Source” that has the following fields:
Site
Department
Date
Full_Income
Income_To_Allocate
Payments_To_Allocate
There are 4 Sites (SiteA/SiteB/SiteC/SiteD), Sites B-D have only 1 department and Site A has 10 departments.
This table is “mostly” a daily summary. I say “mostly” as the daily detail from 2018 was lost and instead we just have the monthly summary inputted as one entry on the last day of the month. For 2018 there is only data going back to September. From 1/1/2019 the summary is actually daily.
Any Income in the Full_Income field will be given to that Site/Department at 100% value.
Any Income in the Income_To_Allocate field will be spread among all the Site/Departments using the below logic:
(
(Prior_Month_Site_Department_ Balance+ This_Month_Site_Department_Full_Income)
/
(Prior_Month_All_Department_Balance + This_Month_All_Department_Full_Income)
)
*
(This_Month_All_Department_Income_to_Allocate)
Any Payments in the Payments_to Allocate) field will be spread among all the Site/Departments using the below logic:
(
(Prior_Month_Site_Department_ Balance+ This_Month_Site_Department_Full_Income)
/
(Prior_Month_All_Department_Balance + This_Month_All_Department_Full_Income)
)
*
(This_Month_All_Department_Payments_to_Allocate)
The idea behind these pieces of logic is to spread the allocated pieces based on the % of business each Site/Department did when looking at the Full_Income data.
The Balance would be calculated with this logic:
Start Balance:
Prior day Ending Balance
Ending Balance:
Prior day Ending Balance + (Site_Department_Full_Income) + (Site_Department_Allocated_Income)- (SiteDepartment_Allocated_Income)
I have tried to do things using the lag function to grab the prior info that I am needing for these calculations. I always get real close but I always wind up stuck on the fact the Ending Balance is calculated using the post spread values for the allocated income and reseeds while the calculation for the spread is using the prior month balance info. This ends up being almost circular logic but with a finite start point. I am at a loss for how to make this work.
I am using SQL Server 2012. Let me know if you need any more details.

SSAS MDX Calculation - Sum based off a group value

I work for a hotel company and I have set up a fact table with the granularity of a stay night for each guest, e.g. if a guest stays for 3 nights, there would be a row for each night of the stay.
What I am trying to do is create a measure for the occupancy percentage (rooms booked divided by available rooms).
I have a column in the fact table that says how many rooms the hotel has, but just summing up that value doesn't work because then it is just multiplying the number of rooms by the number of guests. So I need to sum up the total guests and then divide by the number of rooms that that particular hotel has. Does this make sense?
[Measures].[On The Books] / [Measures].[Rooms Available]
The SQL for this would this:
SELECT stay.PropertyKey, prop.RoomsAvailable, stay.StayDateKey, COUNT(stay.Confirmation) AS Confirmation,
CAST(COUNT(stay.Confirmation) AS DECIMAL(13,9)) / CAST(prop.RoomsAvailable AS DECIMAL(13,9)) AS OccupancyPercentage
FROM dbo.FactStayNight stay
INNER JOIN
(
SELECT DISTINCT PropertyKey, RoomsAvailable
FROM dbo.FactStayNight
) prop
ON stay.PropertyKey = prop.PropertyKey
GROUP BY stay.PropertyKey, stay.StayDateKey, prop.RoomsAvailable
Your fact table is good, apart from the column with total number of rooms. The fact row is at the granularity level "Room", but the total number of rooms is at granularity level "Entire Hotel".
(You can imagine a "Real estate assets" hierarchy dimension, assuming you don't have one:
Hotel
Floor
Room
)
Possible solutions:
Add a "number of rooms" available in your Date dimension, at the Day level (strictly, "Night" level). This will sum commensurably with COUNT(Guests staying on that day). You could even adjust this number to reflect e.g. rooms under repair in particular periods.
You could implement a Room dimension, with each guest's Fact_NightStayed assigned to a Room. Then make what is technically called a "headcount" table, just like your Fact_NightStayed. But this table would be a "roomcount" table: a row indicates that a room exists on a particular day (or, if you decide, that a room exists and is usable i.e. not broken/being repaired). Pre-populate this table with one row per room per date, into the future up to a date you decide (this would be an annual refresh process). Then, joining Fact_NightStayed to Fact_RoomCount, your measure would be COUNT(NightStayed)/COUNT(RoomCount).
Watch out for aggregating this measure (however you implement it) over time: the aggregation function itself from the Day leaf level up the Date hierarchy should be AVG rather than SUM.

Powerpivot sum from dimension table

I am a graduate intern at a big company and I'm having some trouble with creating a measure in PowerPivot.
I'm quite new with PowerPivot and I need some help. I am the first person to use PowerPivot in this office so I can't ask for help here.
I have a fact table that has basically all journal entries. See next table. All entries are done with a unique ID (serialnumber) for every product
ID DATE ACCOUNT# AMOUNT
110 2010-1-1 900 $1000
There is a dimension table with has all accounts allocated to a specific country and expense or revenue.
ACCOUNT# Expense Country
900 Revenue Germany
And another dimension table to split the dates.
The third dimension table contains product information, but also contains a column with a certain expense (Expense X).
ID Expense X ProductName Productcolour
110 $50 Flower Green
I made sure I made the correct relations between the tables of course. And slicing works in general.
To calculate the margin I need to deduct this expense x from the revenue. I already made a measure that shows total Revenue, that one was easy.
Now I need a measure to show the total for Expense X, related to productID. So I can slice in a pivot table on date and product name etc.
The problem is that I can't use RELATED function because the serial number is used multiple times in the fact table (journal entries can have the same serial number)
And if I use the SUM or CALCULATE function it won't slice properly.
So how can I calculate the total for expense X so it will slice properly?
Check the function RELATEDTABLE.
If you create a dummy dataset I can play around and send you a solution.

"Average" aggregation of sparsely populated percentage values

I have cost center allocation data that is currently fully populated, one record per day, each with one cost center dimension key. The cube has a head count measure (the data is set to "1"), and the aggregate function is set to "LastChild". This means that a head count report will count a person only once in a cost center in any given time period.
Introducing partial allocations - a new measure will have a percentage value for the allocation, allowing for multiple concurrent cost centers where the allocation should add up to 100% (with "day" being the granular level). I am trying to figure out how to configure the aggregation over other time periods. I thought that "Average" should work just fine, i.e. a person who is allocated to a cost center at 50% for half the time period will be reported at 25% for that period.
The problem that I see is that my facts are not populated for days where the allocation to a cost center was 0%. To illustrate:
Employee1 CostCenterA 1/1/2013 50%
Employee1 CostCenterB 1/1/2013 50%
Employee1 CostCenterA 1/2/2013 100%
Employee1 CostCenterA 1/3/2013 100%
... etc with 100% in CostCenterA for all days
The above data on a report by month shows 50% for the allocation to CostCenterB, even though the person was only allocated for one day, and the average percentage on a monthly basis should be 1.6%.
I suppose I could generate the 0%-allocations in the data, but my fact table would explode as a result, so I'd much rather change how the "average" aggregation treats percentage values in facts that are sparsely populated, i.e. the average should be calculated based on the number of granular units in the reporting period (days in the month, in this case 0.5/31), not the number of rows in the fact table (0.5/1). Can this be done in SSAS?
If the measure with the average allocation is off by a factor that is proportional to the "sparseness" of my facts, i.e. the ratio of days in a period and actual fact rows, then it can be corrected as follows:
adjusted average allocation =
(calculated average allocation) * (fact count)/(number of days in period)
I created two new hidden measures, one named [Fact Count] for the fact count (a measure using the AggregateFunction "Count") and a calculated measure named [Days In Period Count] for the number of days, using the expression
COUNT(Descendants([Date].[Calendar].CurrentMember,5),INCLUDEEMPTY)
with [Calendar] being the name of the hierarchy in my Date dimension.
Finally, I added a calculated measure that implements the corrective formula:
[Measures].[Allocative Head Count]/
(
[Measures].[Days In Period Count]/[Measures].[Fact Count]
)
and named it [Adjusted Average Allocation]. This I can now use in reports and it appears to somewhat approximate the average cost center allocation over longer periods.
The formular for [Days In Period Count] btw does not work for the row totals when filters are involved. I opened another question for this.

Predictive Ordering Logic

I have a problem and was wondering if anyone could help or if it is even possible to have an algorithm for something like this.
I need to create a predictive ordering wizard. So based on previous sales, we will determine that that a certain amount of an item is required. E.g 31 apples. Now i need to work out the number of cases that needs to be ordered. If the cases come in say 60, 30, 15, 10 apples, the order should be a case of 30 and a case of 10 apples.
The number of items that need to be ordered change in each row of the result set. The case sizes could also change for each item. So some items may have an option of 5 different cases and some items may land up with an option of only one case.
Other examples would be i need 39 cans of coke and the cases come in only 24 per case. Therefore needing 2 cases. I need 2 shots of baileys and the bottle of baileys come in 50cl or 70cl. Therefore i need the 50cl.
The results sets columns are ItemName, ItemSize, QuantityRequired, PackSize and PackSizeMultiple.
The ItemName is the item to be ordered. ItemSize is the size the item is used in eg. can of coke. QuantityRequired how man of the item, in this case cans of coke, need to be ordered. PackSize is the size of the case. PackSizeMultiple is the number to multiply the item with to work out how many of the items are in the case.
ps. this will be a query in SQL Server 2008
Sounds like you need a UOM (Unit of Measure) table and a function to calc co-pack measure count and and unit count measure qty. with UOM type based on time between orders. You would also need to create a cron cycle and freeze table managed by week/time interval in order to create a freeze view of the current qty sold each week and the number of units since last order. Based on the 2 previous orders to your prior order you would set the current prediction based on min time between the last 2 freeze cycles containing an order and the duration of days between them. based on the average time between orders and the unit qty in each order, you can create a unit decay ratio percentage based on days and store it in each slice forward. Based on a reference to this data you will be able to create a prediction that will allow you to trigger a notice to sales or a message to the client to reorder. In addition, if you engage response data from sales based on unit count feedback from the client, you can reference an actual and tune your decay rate against your prediction. You should also consider managing and rolling up these freezes by month, so that you can view historical trending and forecast revenue based on velocity of reorder and same period last year. Basically this is similar to sales forcasting and we are switching out your opportunity percentage of close with Predicted Remaining Qty. percentage remaining.