MDX conditional sum measure - sum

I have a stock movement table with 4 columns - SKUID, productID, dateIn, dateOut and amount. I wish to be able to track stock levels over time ie on each date in a given range what was the stock level of a given productID - e.g.
(Source Data)
SKUID, productID, dateIn, dateOut, amount
100001, 5, 10/01/2014, 15/01/2014, 500
100002, 5, 10/01/2014, 15/01/2014, 1000
100003, 5, 20/01/2014, 31/12/2049, 500
100004, 5, 20/01/2014, 20/01/2014, 100
(Report Data)
productID, date, amount
5, 10/01/2014, 1500
5, 11/01/2014, 1500
5, 11/01/2014, 1500
...
5, 15/01/2014, 0
5, 15/01/2014, 0
...
5, 20/01/2014, 500
5, 21/01/2014, 500
For each day in the final report I want to see the sum of amount for each product where the dateIn is <= reportDate and dateOut is >= reportDate.
I think this should be done as some kind of conditional sum - ie create a calculated measure as follows :-
sum({null:[dateIn].[Date].CurrentMember}, iif([StockMovement].[dateOut] >= [dateIn].[Date].CurrentMember, [Measures].[Amount], 0))
this doesn't work - it simply gives me the sum of amount for each dateIn

You shouldn't do this. Even if you can, it's not a good idea.
The table you describe has a grain that can be more or less identified as "shipments", where each shipment is indivisible. Ok, that gives you measures like "number of days per shipment", or "amount going in on date X" or "amount going out on day X".
If you want to track inventory you should use a snapshot fact table, where for each day you add 1 record per product with the amount currently in stock. So, for each day, you take the previous day stock level, add all amounts in, subtract all amounts out and store it on an inventory table.
Check The Data Warehouse Toolkit by Ralph Kimball, look into the Inventory chapter where he describes snapshot fact tables and why we need them. He explains quite well how your approach may have undesirable effects.

Related

How do I make an SQL query in Postgres that finds total balance and applies credit fees for the year?

I am totally new to Postgres and I cant find any example of what I am trying to do...
I have a table of transactions for a year:
amount | date
12 | 1980-02-12
-200 | 1980-03-06
30 | 1980-03-14
Positive transactions for incoming money.
Negative transactions for credit payments.
And I need to return a total for the year that also reflects charging a $20 fee for every month where less than $400 in credit was used, like so:
total
-------
80,401
My thought was that I would first find total credit for all months like this...
WITH month_credit_totals
AS
(SELECT
SUM(amount) AS total_credit
FROM transactions
WHERE amount < 0
GROUP BY DATE_TRUNC('month', date))
and from there I would find the amount of months with less than $400 in credit payments like this...
SELECT
COUNT(*)
FROM month_credit_totals
WHERE total_credit <= -400
I wanted to save off this number, subtract it from 12, multiply that result by -20, and get the total amount owed in credit fees for the year that way.
Then, I thought I could just total up the amount column, apply that total fee amount, and that would be my result.
But I am having so much trouble understanding the syntax as a complete beginner, I cant find a way to save off variables, do the math, and apply that to total. I am constantly getting syntax errors that are pointing me in no direction just when I try to declare a variable at all.
Maybe I'm going about this the completely wrong way?
I would appreciate any advice. Thanks!
You're on the right track, but you don't really need to save these variables anywhere, just calculate it on the fly.
WITH credit_by_month AS
(
SELECT DATE_TRUNC('month', dt), SUM(amount) AS total_credit
FROM transactions
WHERE amount < 0
GROUP BY DATE_TRUNC('month', dt)
)
SELECT COUNT(*) * 20 AS credit_fee
FROM credit_by_month
WHERE total_credit > -400
Here's a working demo on dbfiddle, it's using random data so it will return a different number every time.

AWS QuickSight: maxOver() calculated field?

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.

AR Aging DAX Pattern

I'm trying to create a measure that displays buckets of AR values from our accounting system. The billing table is structured in a way where a row is created for each financial transaction related to a bill: one record shows the billed amount and a separate record, related by a bill key, shows one or more payments to the bill. I am able to create multiple measures that sum the bill amounts and break these out by Current, 30, 60, 90 and 120 day buckets (admittedly, this is new to me so even this measure might not be right):
AR Current =
VAR EndDate = TODAY()
VAR StartDate = EndDate - 29
RETURN
CALCULATE(
[Billings],
DATESBETWEEN(
'Date'[Date], StartDate, EndDate
)
)
The issue I have is trying to sum up the collections. The collections are not aged, but the total amounts collected for a specific bill need to be subtracted from the total billings in each aging bucket. Regardless of the date range, I need to get a list of all Bill Keys for each bucket, use those keys to sum the values for the Collections column, and subtract from the total within a bucket.
The only equivalent I can think of is a SQL query:
--This example gets the billed amount for anything less than 30 days old)
SELECT BILLKEY, SUM(BILLAMOUNT) BILLAMOUNT
FROM tblBilling
WHERE BILLDATE BETWEEN GETDATE()-30 AND GETDATE()
GROUP BY BILLKEY
-- This gets the corresponding collections:
SELECT BILLKEY, SUM(COLECTION) COLLECTION
FROM tblBilling
WHERE BILLKEY IN (
SELECT BILLKEY FROM tblBillings WHERE BILLDATE BETWEEN GETDATE()-30 AND GETDATE()
)
GROUP BY BILLKEY
Any help would be greatly appreciated.
Thanks,
Eric

MDX - sum costs up to a given date

This is a slight modification of what I stumbled upon while searching the web:
Let's say I have a dimension PROJECTS which contains:
project_id - unique id
category - category of a cost
project_date - date of summing up the cost
My warehouse also has the dimension of TIME with date, and a dimension COSTS containing values of costs. Those three dimensions are connected by the measure group EXPENSES which has:
id_date
id_cost
id_project
I want to wirte an MDX query which would group the projects by their category, and sum up all the costs, but only those which do not exceed the date given in the project_date attribute of the dimension PROJECTS (each category has the same project_date, I know it's redundant but I can't change it..)
I'm not sure, but maybe something alongside this?
SELECT
[COSTS].[COST] ON 0,
[PROJECTS].[category] ON 1
FROM [CUBE]
WHERE
[PROJECTS].[project_date] < #project_date

SQL Conditional select - calculate running total

I have a stored procedure that calculates requirements for customers based on input that we receive from them.
Displaying this information is not a problem.
What I'd like to do is show the most recent received amount and subtract that from the weekly requirements.
So if last Friday I shipped 150 items and this weeks requirements are 100 items for each day then I'd like the data grid to show 0 for Monday, 50 for Tuesday, 100 for Wednesday - Friday.
I have currently tried using with limited success the sample select statement -
Select Customer, PartNumber, LastReceivedQty, Day1Qty, Day2Qty, Day3Qty, Day4Qty, Day5Qty,
TotalRequired
FROM Requirements
Obviously the above select statement does nothing but display data as it is in the table. So when I add the case state as follows I get a bit closer to what I need but not fully and I'm unsure how to proceed.
Select Customer, PartNumber, LastReceivedQty,
"Day1Qty" = case When Day1Qty > 0 then Day1Qty - LastReceivedQty end
...
This method works ok as long as the LastReceivedQty is less than the Day1 requirements but it's incorrect because it allows a negative number to be displayed in day one rather than pulling the remainder from day2.
Sample Data looks like the following:
Customer PartNumber LastReceivedQty Day1Qty Day2Qty Day3Qty Day4Qty Day5Qty TotalRqd
45Bi 2526 150 -50 100 100 100
In the sample above the requirements for part number 2526 Day 1 are 100 and the last received qty is 150
The day1qty shows -50 as opposed to zeroing out day 1 and subtract from day2, 3, etc.
How do I display those figures without showing a negative balance on the requirement dates?
Any help/suggestions on this is greatly appreciated.