DAX Time Intelligence Function - pivot-table

I would like to Calculate the MTD, YTD of Sales
I would like to ask if these two queries give different result.
TotalMTD 1 := TOTALMTD(SUMX(Sales,Sales[Amount]),Sales[Date])
TotalMTD 2 := TOTALMTD(SUM(Sales[Amount]),Date[Date])
What is the different when using Date Table as Date Column as compare to Date Column from the object of analysis?

[TotalMTD 1] will perform a cumulative total over each context. In other words it calculates the SUMX() for the first context then will sum that total to the next context total and that total to the next context an so on until reach the Sales[Date] current evaluated context.
Note SUMX(Sales,Sales[Amount]) takes the entire table Sales table to evaluate each context and perform the calculation until the current sales date.
[Total1MTD 2] contrary to [TotalMTD 1] measure, calculates the total per context, no cumulative total is performed there since SUM() is evaluated for each context.
For example, consider this simple dataset, in this example the context is Category:
Category Amount Month --> This can be any date of month 1
A 100 1
A 100 1
B 50 1
B 50 1
C 50 1
C 50 1
C 50 1
Your measures should produce:
Category TotalMTD 1 TotalMTD 2
A 200 200
B 300 100 TotalMTD1 ----> Sum A total to B total
C 450 150 TotalMTD1 ----> Sum A + B to C total
Also be aware of the Mark a Date Table setting since that could make both measures result different. You can Mark a table as Date Table column which affects your filters and metadata used by client applications to represent your model. If you marked your Date table as the Date Table of your model it will apply an ALL(Date) in each measure where you use Date[Date] column, i.e. your measure will be implicitely converted to:
TotalMTD 1 := TOTALMTD(SUMX(Sales,Sales[Amount]),Sales[Date],ALL(Date))
Which obviously performs a different calculation.
Additional information:
Time Intelligence functions are supposed to be used with the date column from a calendar/date table. That column should be a consecutive and secuencial key.
In order to work with time-intelligence functions, you need to have a date table included in your Data Model. The date table must include a column with one row for every day of each year included in your data.
REFERENCE 1
REFERENCE 2
Let me know if this helps.

Related

Average for loop in loop PL / SQL

I am trying to calculate the avarage of durations from the last 40 days for diffrent IDs.
Example: I have 40 days and for each day IDs from 1-20 and each ID has a start date and end date in HH:MI:SS.
My code is a cursor which fetches the last 40 days, then I made a second for loop. In this one I select all the ids from this day. Then I go through every ID for this day and select start and end dat calculating the duration. So far so good. But how do I calculate the avarage of the duration for the IDs in the last 40 days.
The idea is simple. To take the durations for one id (in the last 40 days) add them together and divide them by 40. And then do the same for all IDs. My plan was to make a 2d Array and in the first array putting all IDs, then in the second array to put the duration and add the values for one id together. Then I would have added all the durations for one ID together and get the value from the array. But I am kinda stuck in that idea.
I also wonder if there is a better solution.
Thanks for any help!
From my point of view, you don't need loops nor PL/SQL - just calculate the average:
select id,
avg(end_date - start_date)
from your_table
where start_date >= trunc(sysdate) - 40
group by id
Drawback might be what you said - that you stored dates as hh:mi:ss. What does it mean? That you stored them as strings? If so, most probably bad idea; dates (as Oracle doesn't have a separate datatype for time) should be stored into DATE datatype columns.
If you really have to work with strings, then convert them to dates:
avg(to_date(end_date, 'hh:mi:ss') - to_date(start_date, 'hh:mi:ss'))
Also, you'll then have to have another DATE datatyp column which is capable of saying what "last 40 days" actually means.
Result (the average) will be number of days between these values. Then you can format it prettier, if you want.

Measure that indicates sales volume per product per day (Google Data Studio)

I need to implement a measure that indicates sales volume per product per day. For the example table below (each line is a record of a sale):
id,create_date,report_date,quantity
329,2019-01-02 08:19:17,2019-01-02 14:34:12,6
243,2019-01-02 09:11:42,2019-01-03 15:30:14,6
238,2019-02-02 08:19:17,2019-03-02 14:36:17,2
170,2019-04-02 02:15:17,2019-04-02 14:37:12,2
238,2019-04-02 08:43:11,2019-04-02 14:41:01,8
238,2019-04-02 08:52:52,2019-04-02 14:39:12,1
238,2019-08-02 08:10:09,2019-08-02 15:02:12,1
238,2019-10-02 08:10:17,2019-10-02 18:34:11,1
170,2020-01-02 08:24:14,2020-01-02 19:31:31,2
170,2020-01-02 08:32:16,2020-01-02 21:52:32,3
The operations to reach the result:
1. Identify total sales and total products for each day.
For 2019-01-02, two sales were carried out, totaling 12 products (6 products for each sale on the day)
2. Divide total products by total sales, resulting in the product/sale ratio for the day (if the result is 2, it indicates that each sale on average corresponds to two products).
In the example table there are 6 different dates (YYYMMDD), for each corresponding date: total products/amount of sales on the day (12/2, 2/1, 11/3, 1/1, 1/1, 5/1) .
3. Average every day's story, resulting in a single value.
(3 + 2 + 3.6 + 1 + 1 + 3)/6 = 2.26 , indicating that on average two products are sold per sale per day.
As it involves many operations, I couldn't get a solution for this problem. If anyone can help me.
note: I accept alternative suggestions to offer the measure to indicate the volume of sales per product per day.
Please check the numbers given in your steps 2 and 3:
12/2=6 not 3
5/1 must be 5/2
I still think that you want to calculate a 'day story' in step 2, see formular below.
Here are the steps for generating such a value:
create a table
add your time as dimension and make it to date not date&time
order by date ascending (optional)
create a field day story with the formula sum(quantity)/count(id)
add this field three times to your table
click on the AUT left to the fieldname and select Running calculation to 'running average`
You have to convince your users to only look at the last line of the table.

Qlikview Pivot Table Top X by week

I have a pivot table with week number (columns) versus product (rows). I want to see the top 10 products, based on sales, per week, a value of 1 would indicate the product is in the top 10. I'm using the expression below and I'm getting the Top 10 sales over all weeks. How do I get a weekly top 10 (each column would have ten values)?
=if(Aggr(Rank(sum([SALES])),PRODUCT)< 11,1,0)
I would say you are almost there, but you need to add another parameter to the Aggr function (like you've said you want the rank by Product and Week, and currently you are only taking Product into account).
Without knowing the details of your model, the expression would be something like :
=if(Aggr(Rank(sum([SALES])),PRODUCT,WEEK)< 11,1,0)

Current Record Calculated Field on Previous Record Calculated Value

In this example, there are 5 periods of actual balances and the implied depreciation rates. Starting in Period 6, need the Balance to be calculated on previous period balance ($8,177,480) * the current period depreciation rate (-1.50%) and so on. I've heard recursive CTE but I am not familiar with them.
Period DeprRate Balance Comment
1 0% $10,000,000 Actual Values
2 -1.62% $9,838,000 Actual Values
3 -7.41% $9,109,004 Actual Values
4 -8.00% $8,380,284 Actual Values
5 -2.42% $8,177,481 Actual Values
6 -1.50% null should be $8,177,481*(1-.015)
7 -1.50% null should be Pd 6 Calc Balance *(1-.015)
8 -5.73% null should be Pd 7 Calc Balance *(1-.0573)
9 -4.13% null should be Pd 8 Calc Balance *(1-.0413)
10 -1.50% null should be Pd 9 Calc Balance *(1-.015)
CREATE TABLE Table1
([Period] int, [DeprRate] float, Balance integer)
;
INSERT INTO Table1
([Period], [DeprRate], Balance)
VALUES
(1,0,10000000),
(2,-0.0162,9838000),
(3,-0.0741,9109004.2),
(4,-0.08,8380283.864),
(5,-0.0242,8177480.9944912),
(6,-0.015,null),
(7,-0.015,null),
(8,-0.0573,null),
(9,-0.0413,null),
(10,-0.015,null)
"This seems relatively easy, but can't get it."
Yes, it is. Did you follow these steps ?
"I have 10 periods of actual balances and the implied depreciation rates."
Step 1 : Create a table (Table_1) and populate it with these values.
" Starting in Period 11, need the Balance to be calculated on previous period balance * the current period depreciation rate."
Step 2 : Create a query for calculation of new rates based on the values of previous table, execute it and populate it to new table (Table_2).
" Period 11 isn't difficult if that's all that was needed by using lag. Problem is Period 12-20 need to be calculating current period balance on previous period calculated balance multiplied by the current period depreciation rate."
Step 3 : Two options here - one is through a recursive query as 'Vinit' commented. Another option (easy) is to repeat Step 2 and append to Table_2.
=======
Knowledge sharing / Value addition to your question : Depreciation is an Accounting concept, which usually taken into account either in the year end (closing of the books) or at the end of life of an asset. This concept is very tricky as at least two (usually) different calculations may have to be performed to satisfy the tax compliance and also management accounting requirements. Additional calculations may also have to be carried out for each type of asset, just to take decision to determine best possible option.
Though you did not include the date column in your sample data, you should be writing the script to calculate and populate the depreciated values based on a particular date. You can also arrange to execute this script by specifying a trigger as well as through a job agent (scheduling).
Hope this helps.

How do I retrieve the sum of values within a date range without Crystal Reports summing up every value in that column?

My goal is to retrieve the sum of all transactions carried out by a business over a period of time which can be specified by the user.
The transactions are stored on a table which holds a decimal value accompanied with a date.
See an example below
ID Amt Date
1 120.0 19/05/1991
2 240.0 31/06/1991
3 143.0 12/07/1991
4 69.0 02/02/1992
I created a date range parameter and included a running total formula in my report but every time I run the report, it always retrieves the total of all amts even if only a subset of the records are returned by the date range.
The ideal situation would be one in which the sum of all transactions returned only adds up amounts that fall within the specified date range.
Thanks.

Resources