aggregate the average of a calculated member over a certain time - time

Quick Info
i have a Microsoft SQL Server Analysis Project where i have to aggregate the average of a calculated member over the a time range of the past 20 days. And i don´t know how to solve this.
What i have
My calculated member looks like:
CREATE MEMBER CURRENTCUBE.[Measures].[MyTotalSample]
AS [Measures].[ValueA]-[Measures].[ValueB]-[Measures].[ValueC],
VISIBLE = 1, ASSOCIATED_MEASURE_GROUP = 'MySamples';
This [MyTotalSample] Member is related to a [time] dimension,
so i get the [MyTotalSample] for each [Time].[Day].
The result looks like the table below, where for example the value from "January 27 2017" the total of all [MyTotalSample] values for "January 27 2017".
|---------------------------------|
|[Time].[Day] | MyTotalSample |
|---------------------------------|
|January 27 2017 | 221 |
|January 28 2017 | 303 |
|January 29 2017 | 298 |
|January 30 2017 | 238 |
|---------------------------------|
That works so far.
PROBLEM
But what i want to do also is a per day average of [MyTotalSample] within the range from the current day to 20 days in the past.
To get something like the table below, where the value from "January 27 2017" the average value of [MyTotalSample] in a the range from "January 27 2017" to "January 08 2017".
|------------------------------------|
|[Time].[Day] | MyTotalSample(Avg)|
|----------------|-------------------|
|January 27 2017 | 224 |
|January 28 2017 | 228 |
|January 29 2017 | 231 |
|January 30 2017 | 226 |
|------------------------------------|
What would be perfect is to ignore the null values... but that not so important right now...
I hope someone has experience with that and could give me a strategie how to do this...
Thanks you for taking time
Felix

We found a solutions in a msdn!
CREATE MEMBER CURRENTCUBE.[MEASURES].[MyTotalSample Moving Average]
AS Avg
(
{
[Time].[Hierarchy].CurrentMember.Lag(20)
:
[Time].[Hierarchy].CurrentMember
}
,
[Measures].[MyTotalSample]
),
VISIBLE = 1 , DISPLAY_FOLDER = 'MyDisplayFolder';

Related

How to make SELECT that returns TIMESTAMP and a value per minute within the current quarter hour?

I have a table as below, and I need select to return the value per minute within the current quarter. For example, if now it's 15:19, I need select to return TIMESTAMP and the value in this quarter between 15:15 and 15:30.
That is, I need select to return the last minutes of the current quarter of an hour. DB is ORACLE.
TIMESTAMP | VALUE
11/11/2019 15:09 | 45
11/11/2019 15:10 | 10
11/11/2019 15:11 | 15
11/11/2019 15:12 | 35
11/11/2019 15:13 | 55
11/11/2019 15:14 | 25
11/11/2019 15:15 | 20
11/11/2019 15:16 | 22
11/11/2019 15:17 | 12
11/11/2019 15:18 | 10
11/11/2019 15:19 | 21
I have tried TRUNC, but no success.
You need trunc by 15 mins.
You can do it using following logic:
Select * from your_table
Where your_timestamp_col
between trunc(systimestamp,'dd') + floor(to_char(systimestamp,'sssss.ff') / 900) / 96
And trunc(systimestamp,'dd') + ceil(to_char(systimestamp,'sssss.ff') / 900) / 96
Here, 900 represent seconds in 15 mins and 96 represents total such quarters in a day (24 hours * 4 quarters = 96)
Cheers!!

Splitting char to multiple rows in Oracle

The table is as follows:
YEAR | MONTH | HOLIDAY |
2015 | 10 | # # # ### |
2015 | 11 | # # # # # |
I want to create the following:
YEAR | MONTH | DATE | VALUE |
2015 | 10 | 01 | # |
2015 | 10 | 02 | |
2015 | 10 | 03 | |
2015 | 10 | 04 | # |
UNTIL
2016 | 11 | 30 | # |
I've seen a few solutions around stack but It couldn't work
Any help would be greatly appreciating
Well, I'm not sure why you would want to go to November 31st, a date that doesn't exist. But, here is an idea:
with n as (
select level as n
from dual
connect by level <= 31
)
select t.year, t.month, n.n as day,
substr(t.holidays, n.n, 1) as holiday
from t join
n
on n.n <= length(t.holiday);

How to insert sum value to another table using procedure oracle

I want to make a table that contains summary value from another table; the purpose is to make a balance sheets report. I'm new in Oracle database so I'm still confused regarding how to do that. Is it using procedure, if yes so how to do it?
Here is the example data
In table 1 :
Year | Periode | Date Trx | Debit | Credit
2014 | Jan | 2/1/2014 | 50 | 0
2014 | Jan | 3/1/2014 | 0 | 20
2014 | Feb | 2/2/2014 | 0 | 100
2014 | Feb | 6/2/2014 | 50 | 0
2015 | Mar | 2/3/2014 | 0 | 80
2015 | Mar | 8/3/2014 | 50 | 0
2015 | Okt | 2/10/2014| 50 | 0
And I want the result in table 2 to like this:
Year | Periode | Debit | Credit
2014 | Jan | 50 | 20
2014 | Feb | 50 | 100
2015 | Mar | 50 | 80
2015 | Okt | 50 | 0
I hope someone could tell me how to make the procedure
from the sample that you provided - it can be resolved
via simple sql. it's common sql and no specific oracle features are required here
select year, period, sum(debit) as debit, sum(credit) as credit
from my_table
group by year, period
As #are notes a procedure is not needed here - but if you really insist on using one it would look something like
CREATE OR REPLACE PROCEDURE POPULATE_BALANCE_SHEET_REPORT IS
BEGIN
INSERT INTO TABLE2
SELECT YEAR, PERIODE, SUM(DEBIT), SUM(CREDIT)
FROM TABLE1
GROUP BY YEAR, PERIODE;
END POPULATE_BALANCE_SHEET_REPORT;
Best of luck.

Algorithm to calculate automatic adjusted statements according to payment amount

Background:
I decided to make a plan to save let´s say 1200 Euros in 6 months.
The problem is that I could not say that I will save 200 per month because sometimes I have to spend more and sometimes I might have a bonus or something.
For example, in the first month I could save only 100 Euros. Thus, I would like to split the remaining 100 in the other 5 remaining months: 20 euros more each month.
Original plan:
Jan | Feb | Mar | Apr | May | Jun
200 | 200 | 200 | 200 | 200 | 200 -> Total is 1200
Actual plan for the first month
Jan | Feb | Mar | Apr | May | Jun
100 | 220 | 220 | 220 | 220 | 220 -> Total is still 1200
Then, on February I got my bonus and could save 300 instead of 220. So now I will divide the extra 80 bucks in the remaining 4 months. Since it was more than I should have saved, now I will subtract. 80/4 = 20
Actual for the second month:
Jan | Feb | Mar | Apr | May | Jun
100 | 300 | 200 | 200 | 200 | 200 -> Total is still 1200
Question: What would be the algorithm to automatically adjust the value to be saved for the remaining installments according to the i (month in question), goal (final amount, constant) and amount already deposited?
Is it possible to represent this 3 parameters in a function?
Thank you
It is actually not an algorithm, it is simple math. Assume that you are on month i(a value from 1 to 6) and so far(for months 1, 2... i-1) you've saved X dollars. Then for the remaining months, you need to save (1200 - X) / (6 - i + 1). I divide by (6 - i + 1) because this is the number of months from i-th inclusive.

Pl/SQL and building out monthly data from Start and Stop Dates

PL/SQL is not my strong suite. I am decent with SQL, but I have a challenge that I could really use your help with, if possible. I am using SQL Developer, if that helps.
I have a table that is a join from two other tables, but suffice it to say, it has the following applicaple columns:
FTE_NAME (VARCHAR2)
PRIMARY_BILLALBE_ROLE (VARCHAR2)
INVOICABLE_ALLOCATION (NUMBER)
CONTRACTED_FTE (NUMBER)
FTE_COUNTRY (VARCHAR2)
BILLING_START_DATE (DATE)
BILLING_END_DATE (DATE)
Here is an example of what I am trying to do:
I have actually done this using VBA and excel and it works great, but now the data is on an Oracle Server and its time for an update.
Example Rows:
| FTE_NAME | PRIMARY_BILLABLE_ROLE | INVOICEABLE_ALLOCATION | CONTRACTED_FTE | FTE_COUNTRY | BILLING_START_DATE | BILLING_END_DATE |
|------------|-----------------------|------------------------|----------------|-------------|--------------------|------------------|
| John Smith | Associate Manager | 1 | 1 | USA | January, 01 2013 | May, 01 2013 |
| John Smith | Manager | 1 | 1 | USA | May, 02 2013 | (null) |
What I would need to happen is that the PL/SQL code would build a monthly table and row by row include or exclude the row in that month, so from 01-JAN-2013 to 05-MAY-2013, the monthly table might look like this now with a MONTH COLUMN up front:
| MONTHLY | FTE_NAME | PRIMARY_BILLABLE_ROLE | INVOICEABLE_ALLOCATION | CONTRACTED_FTE | FTE_COUNTRY | BILLING_START_DATE | BILLING_END_DATE |
|-------------------|------------|-----------------------|------------------------|----------------|-------------|--------------------|------------------|
| January, 01 2013 | John Smith | Associate Manager | 1 | 1 | USA | January, 01 2013 | May, 01 2013 |
| February, 01 2013 | John Smith | Associate Manager | 1 | 1 | USA | January, 01 2013 | May, 01 2013 |
| March, 01 2013 | John Smith | Associate Manager | 1 | 1 | USA | January, 01 2013 | May, 01 2013 |
| April, 01 2013 | John Smith | Associate Manager | 1 | 1 | USA | January, 01 2013 | May, 01 2013 |
| May, 01 2013 | John Smith | Associate Manager | 1 | 1 | USA | January, 01 2013 | May, 01 2013 |
| May, 01 2013 | John Smith | Manager | 1 | 1 | USA | May, 02 2013 | (null) |
The lines for MAY would both be included in the 01-MAY-2013 rows, because that manager still worked as an Associate Manager for those few days. I used the start and end dates to calculate how many days.
The big part I need help with is how to get the table to build with a MONTHLY column using the first day of the month. There will 1000s of lines and each building everyday. I would have this code running in a view which will feed report and dashboards.
I really appreciate any help you can provide.
David
You can populate desired dates from scratch like in this example query:
with report_params as (
-- just to introduce variables
select
2013 year_value,
4 start_month,
6 end_month
from dual
),
report_months as (
-- list of first dates of all required months
select
add_months( -- add months to
trunc( -- January, 1st of year from parameters
to_date(
(select year_value from report_params),
'yyyy'
),
'yyyy'
),
(select start_month from report_params) + level - 2
)
from
dual
connect by
-- select number of rows (levels) from start_month to end_month
level <= (select end_month - start_month + 1 from report_params)
)
select * from report_months;
Another possibility is to analyze a table and generate diapason between minimum and maximum values:
with bound_months as (
select
min(trunc(billing_start_date,'mm')) as first_month,
max(trunc(billing_start_date,'mm')) as last_month
from
applicable_columns
),
report_months as (
select
add_months(
(select first_month from bound_months),
level - 1
)
as first_date
from
dual
connect by
-- select number of rows (levels) from start_month to end_month
level <= (select months_between(last_month,first_month)+1 from bound_months)
)
select * from report_months;
After that you can join list of months to data table/view with applicable columns:
with bound_months as (
select
min(trunc(billing_start_date,'mm')) as first_month,
max(trunc(billing_start_date,'mm')) as last_month
from
applicable_columns
),
report_months as (
select
add_months(
(select first_month from bound_months),
level - 1
)
as first_date
from
dual
connect by
-- select number of rows (levels) from start_month to end_month
level <= (select months_between(last_month,first_month)+1 from bound_months)
)
select
months.first_date,
data.*
from
report_months months,
applicable_columns data
where
data.billing_start_date < add_months(months.first_date,1)
and
nvl(data.billing_end_date, months.first_date) >= months.first_date
order by
first_date, fte_name, primary_billable_role
SQLFiddle test

Resources