I have [Measures].[Days in the period] which calculates number of days for my Time hierarchy.
I want to create the calculated member that will return number of days until today. For example, if today is 14 of November it must show 14 days for November (not 30). And nulls for upcoming months (December, for example). There is nothing like GetDate() from SQL, so I'm a bit confused about easy way to implement it. My initial code doesn't have much:
member [Measures].[Days in the period passed] as [Measures].[Days in the period]
Resolved it myself. The code below does the job:
WITH
MEMBER [Measures].[Days in the period passed] AS
FILTER
(
Descendants([Time].[Calendar], [Time].[Calendar].[Day]),
[Time].[Day].Properties("Day key") <= FORMAT(NOW(), "yyyyMMdd")
).COUNT
EDIT: more elegant and correct way is the scope:
SCOPE
(
[Measures].[Days in the period passed], [Time].[Day].[Day].Members
);
THIS = IIF([Time].[Day].CurrentMember.Properties( "Key0" ) <= FORMAT(NOW(), "yyyyMMdd"),
[Measures].[Days in the period],
NULL);
END SCOPE;
Checking select:
SELECT
([Time].[Calendar].[Mouth]) ON COLUMNS,
(([Measures].[Days in the period passed])) ON ROWS
FROM [TestCube]
Related
I have inherited a query from an old MS Access DB and cannot for the life of me figure out what was trying to be done in this date parameter function. I normally only use SQL and this seems a bit different. Can any one assist in describing what this logic is doing?
use pdx_sap_user
go
select po_number,
po_issue_date
from vw_po_header
where po_issue_date > getDate() And PO_issue_date < DateAdd("d",-1,DateAdd("m",8,DateAdd("d",-(Day(getDate())-1),getDate())))
You can de-obfuscate it a lot by using DateSerial:
where
po_issue_date > getDate() And
po_issue_date < DateSerial(Year(getDate()), Month(getDate()) + 8, 0)
First: there is no getDate() function in Access. Probably it should be Date() which returns the current date.
Now starting from the inner expression:
Day(Date()) returns the current day as an integer 1-31.
So in DateAdd("d", -(Day(Date())-1), Date()) from the current date are subtracted as many days as needed to return the 1st of the current month.
Then:
DateAdd("m", 8, DateAdd("d", -(Day(Date())-1), Date()))
adds 8 months to the the 1st of the current month returning the 1st of the month of the date after 8 months.
Finally:
DateAdd("d", -1,...)
subtracts 1 day from the date returned by the previous expression, returning the last day of the previous month of that date.
So if you run today 13-Sep-2019 this code, the result will be:
30-Apr-2020
because this is the last day of the previous month after 8 months.
I think the following:
Take the current date
Substract the current day of month -1 to get the first day of current month
Add 8 month to this
Substract 1 day to get the last day of the previous month
So it calculates some deadline in approx 8 months.
But I wonder how a PO issue date can be in the future...
BackStory
I am working in MDX and my measure groups use many calculations. Many of these are timeframes such as [Date].[Fiscal].[LY WTD] which stands for last year week to date.
To calculate this I was using the ParellelPeriods function. However as our calendar has 52 weeks for one year and 53 for the current year my calculations are off.
I have made my changes using
CREATE MEMBER CURRENTCUBE.[Date].[Fiscal].[LY WTD] as
Aggregate(
Exists(
[Date].[Date].[Date].members,
{
[Date].[F Day Of Week].[F Day Of Week].item(0) :
Exists([Date].[F Day Of Week].[F Day Of Week].members, [Date].[Last Complete Day].&[Y]).item(0)
}
* Exists([Date].[F Year].[F Year].members,[Date].[Last Complete Day].&[Y]).item(0).lag(1)
* Exists([Date].[F Week of Year].[F Week of Year].members, [Date].[Current Week].&[Current Week])
)
), VISIBLE = 0;
I now need to test this.
Problem
How can I determine what week my measure [Date].[Fiscal].[LY WTD] is pulling back?
Could you add a test member like this?
CREATE
MEMBER CURRENTCUBE.[Date].[Fiscal].[LY WTD - Caption] AS
Exists
(
[Date].[F Week of Year].[F Week of Year].MEMBERS
,
{
[Date].[F Day Of Week].[F Day Of Week].Item(0)
:
Exists
(
[Date].[F Day Of Week].[F Day Of Week].MEMBERS
,[Date].[Last Complete Day].&[Y]
).Item(0)
}*
Exists
(
[Date].[F Year].[F Year].MEMBERS
,[Date].[Last Complete Day].&[Y]
).Item(0).Lag(1)*
Exists
(
[Date].[F Week of Year].[F Week of Year].MEMBERS
,[Date].[Current Week].&[Current Week]
)
).Item(0).Item(0).Member_Caption
,VISIBLE = 1 ;
I think my problem is that as I am aggregating my calc script it is impossible to then see the individual original members. Here is what I ended up doing.
1. First I used the same script that I was using to make my calculation in a mdx query and ensured I got the dates I expected.
Select
{Measures.[Gross Units]} on 0,
Exists(
[Date].[Date].[Date].members,
{
[Date].[F Day Of Week].[F Day Of Week].item(0) :
Exists([Date].[F Day Of Week].[F Day Of Week].members, [Date].[Last Complete Day].&[Y]).item(0)
}
* Exists([Date].[F Year].[F Year].members,[Date].[Last Complete Day].&[Y]).item(0).lag(1)
* Exists([Date].[F Day of Year].[F Day of Year].members, [Date].[Current Week].&[Current Week])
)
on 1
From myips
Results:
Gross Units 2015/05/09 (null) 2015/05/10 13,069 2015/05/11 35,853
2015/05/12 104,617 2015/05/13 46,318
2. Then I looked for the results, using my calculation for last year week to date and comparing that to a query scoped calculated member aggregated of those days
With Member [Date].[Fiscal].[Custom] as
Aggregate([Date].[Fiscal].[Date].&[2015-05-09T00:00:00]:[Date].[Fiscal].[Date].&[2015-05-13T00:00:00])
Select
[Date].[Fiscal].[Custom]
//Date.Fiscal.[LY WTD]
on 0,
Measures.[Gross Units]
on 1
From myIPS
**I got the same results! Success!**
I have a cube with a 'sales' measure, where we have the amount of sold units each day. We have a time dimension with 'Year > week > day'.
I need to have the sales for the first and the last day in a period with non empty sales for a calculated field. I tried with OPENINGPERIOD and CLOSINGPERIOD but they return for a week period just Monday and Sunday... the problem is that sometimes Monday is holiday and Sunday is always holiday and I get empty data (we have no sales on holidays)... Here is my example for last day of a period:
WITH
MEMBER
[Measures].[sales end] AS
'((CLOSINGPERIOD([Time.Weeks].[Day],[Time.Weeks].CurrentMember)
, [Measures].[sales]))'
SELECT
{[Measures].[sales], [Measures].[sales end]} ON COLUMNS,
NON EMPTY
({[Time.Weeks].[Week].Members}) ON ROWS
FROM [cubSales]
I need to get the last day with non empty sales in that period... it should be Friday, but if Friday is holiday, it should be Thursday... I mean the last day for the week with a value for the measure sales..
An easy solution could be to just omit holiday days from your time dimension.
Mondrian has no concept of holidays. I would implement my own MDX function with a built-in list of holidays. It's a flexible approach which can be extended to support different holidays from different countries.
Tested on our cube and seems to work ok (just doesn't say anything about holidays!)
SELECT
{
[Measures].[sales]
} ON COLUMNS
,NON EMPTY
Generate
(
[Time.Weeks].MEMBERS
,Tail
(
NonEmpty
(
[Time.Weeks].CurrentMember * [Time.Weeks].[Day].MEMBERS //<<I think .members is generally default but should do the same thing if we are explicit
,[Measures].[sales]
)
)
) ON ROWS
FROM [cubSales];
my user table is as follows:
birhtMonth: int
dayOfBirthday: int
HireDate: Date
REQUIREMENT: i want to get all upcoming birthdays and hire dates (day/month year is excluded here) in next 6 months, putting in consideration that for current month the day should be greater than today, so here's what i did:
#Query("from User u where ( (u.birthMonth in (8,9,10,11,12,1)) or (month(u.hireDate) in (8,9,10,11,12,1)) ) and u.company = :company")
this gets all upcoming birthdays & hire dates in next six months but it gets birthdays & hire dates in this month for days before & after current day, and it should only get results > current day and ignore results < current day in this month.
EXAMPLE:
today's date is 8/3/2013, if there's birthday with birthMonth=8 and dayOfBirth=3 or 2 or 1 it should be ignored only dayOfBirth > 3 in current month is considered, also if there's hirDate like:
2011-08-01
2012-08-02
2012-08-03
they should be ignored too, please advise how to solve this in sql or hql.
Your hireDate is of type Date, so use a date comparison and use between such as:
(hireDate between :toDayParam and :sixMonthLaterParam)
for birthDate, you can compare with lpad(birthMonth, 2, 0) + lpad(birthDate, 2, 0) but you shall care about whether six month later is in next year or current year.
I think your looking for the DATE functions. They can greatly help you out here. Specifically the DATEADD function. Take a look at the code I made here.
SELECT * FROM dbo.product
WHERE dbo.product.stockDate > GETDATE()
AND dbo.product.stockDate < GETDATE() + DATEADD(month, 6, dbo.product.stockDate)
AND dbo.product.expirationDate > GETDATE()
AND dbo.product.expirationDate < GETDATE() + DATEADD(month, 6, dbo.product.expirationDate)
This will guarantee that the stockDate and the expirationDate are greater than the current date and less than the current date + 6 mo. DATEADD works as follows DATEADD(-what you want to increment by-, -how much you want to increment-, -date to add to-).
I want to calculate the clients growth over the time.
So every day i have the total clients per state and per product subscription, and i can calculate the total for every day.
If i want to calculate the growth every day i don't have problems because i use a calculated member with
[Date].CurrentMember-[Date].PrevMember
This works pretty fine, but now i want to calculate the growth on month. So i have to sum all day growths of the month to calculate the month growth, right?
But my problem is that i'm too newbie to MDX and i can't find a way to produce that result (I want to know how many clients i have more or less over the year).
My intuition says that i need to sum all day's growth in the agregate date.
Could you help me?
If your date hierarchy has a month level above the date level (eg. Year-Month-Day), your cube will already have pre-processed this value. I would use ANCESTOR and LAG to get the data for a given day's month:
WITH MEMBER [Date].[YMD].[Current Month] AS
ANCESTOR(
[Date].[YMD].CurrentMember,
[Date].[YMD].[Month Level]
)
MEMBER [Date].[YMD].[Growth this month] AS
(
[Date].[YMD].[Current Month]
-
[Date].[YMD].[Current Month].LAG(1)
)
This will, however, only get the data from a whole-month period.
If what you're after is all the data between a particular day and the same day in the previous month, then PARALLELPERIOD is your go-to function (sidenote: not a goto statement). PARALLELPERIOD(Level, N, Member) will look at the position of Member amongst its siblings, then go to its ancestor at Level, go N members prior to that, and traverse back down to a member in the same relative position as Member.
In other words, it looks up your date in a prior month, year or whatev'.
WITH MEMBER [Date].[YMD].[One Month Ago Today] AS
PARALLELPERIOD(
[Date].[YMD].[Calendar Month],
1,
[Date].[YMD].CurrentMember
)
MEMBER [Date].[YMD].[All data since today last month] AS
(
/* The [Member]:[Member] syntax here is a range */
[Date].[YMD].[One Month Ago Today] : [Date].[YMD].CurrentMember
)
MEMBER [Date].[YMD].[Two Months Ago Today] AS
PARALLELPERIOD(
[Date].[YMD].[Calendar Month],
2,
[Date].[YMD].CurrentMember
)
MEMBER [Date].[YMD].[All data between today last month and today in the previous month] AS
(
[Date].[YMD].[Two Months Ago Today] : [Date].[YMD].[One Month Ago Today]
)
MEMBER [Date].[YMD].[Growth in the last month since the previous month] AS
(
[Date].[YMD].[All data between today last month and today in the previous month]
-
[Date].[YMD].[All data since today last month]
)
Hope this helps.
<3