Wednesday, May 16, 2012

How to: First Day of Last Month & the various combinations

A common requirement is to have default date values in a prompt - see below:


1) It helps limit the data set, and 2) it is a way to tell the end user the format of the input values.

But most of the time, the user will want the values to change as time progresses, i.e. 'default to last month's date range'. In this case, a static variable will not due.

How do you create default dates in the prompt that change as time progresses?

Step 1:

Identify what the default values should be. In the above example, the start date is 'First day of last month' and the end date is 'last day of last month', assuming the current month is May 2012.

First day of last month is created as:

TIMESTAMPADD(SQL_TSI_MONTH, -1, TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE))


Last day of last month is created as:

 TIMESTAMPADD( SQL_TSI_DAY , -(1), TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)) 

Step 2:

The issue is that you cannot add the above 2 functions to a prompt because it is not in a recognized format, it must be in one of the following formats:


 Step 3:

We can enclose the above 2 functions in a logical SQL format that Answers will understand ,as follows  :



SELECT

case when 1=0 then Time."Fiscal Date" else  INSERT FUNCTION HERE
from
'Your-logical-subject area'
END
 
 We must do a case 1=0 operation to force the sql code to always default to the timestampadd function
 Step 4:

Using the above logic:

first day of last month:


SELECT

case when 1=0 then Time."Fiscal Date" else TIMESTAMPADD(SQL_TSI_MONTH, -1, TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)) end

FROM "Subject area - Subject area name"

last day of last month:



SELECT

case when 1=0 then Time."Fiscal Date" else 
TIMESTAMPADD( SQL_TSI_DAY , -(1), TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)) 
 end 
FROM "Subject area - Subject area name"


Step 5:
Paste the above into your prompt with default values as 'SQL Results':
 

 Step 6:

And make sure to cast your prompt value as Date - it defaults to datetime.























 
EXTRA Credit:


What if you have 20 prompts that have this requirement?

Answer: Create 2 dynamic variables in the rpd with the following logic:

First day of last month:

select Last_Day(ADD_MONTHS(SYSDATE,-2))+1 FROM DUAL

Last day of last month:


select Last_Day(ADD_MONTHS(SYSDATE,-1))  FROM DUAL

Note how Oracle does NOT have a first_day function :(


Need other day combinations? First day of last quarter? Last day of next month? First day of last year? 

Use the logic below:




First Day of the Previous Year
TIMESTAMPADD( SQL_TSI_YEAR , -1, TIMESTAMPADD( SQL_TSI_DAY , EXTRACT( DAY_OF_YEAR FROM CURRENT_DATE) * -(1) + 1, CURRENT_DATE)) 
From right to left the first TIMESTAMPADD returns the first day of the current year. The second TIMESTAMPADD removes a year from the returned date for the First Day of the Previous Year.

First Day of the Current Year 

TIMESTAMPADD( SQL_TSI_DAY , EXTRACT( DAY_OF_YEAR FROM CURRENT_DATE) * -(1) + 1, CURRENT_DATE) 
This calculation returns the first day of the year by deducting one less than the total number of days in the year.
 

First Day of the Next Year 
TIMESTAMPADD( SQL_TSI_YEAR , 1, TIMESTAMPADD( SQL_TSI_DAY , EXTRACT( DAY_OF_YEAR FROM CURRENT_DATE) * -(1) + 1, CURRENT_DATE))

 From right to left the first TIMESTAMPADD returns the first day of the current year. The second TIMESTAMPADD adds a year to the date returned which will give the first day of the next year.
 

First Day of the Previous Month 
TIMESTAMPADD(SQL_TSI_MONTH, -1, TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)) 

From right to left the first TIMESTAMPADD returns the first day of the Current Month. The second TIMESTAMPADD then subtracts one month from the first day of the Current Month arriving to the First Day of the previous month.

First Day of the Current Month


TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)


 This expression gets the current day of the month and subtracts one less than the current day to arrive at the first day of the month.
 

First Day of the Next Month 
TIMESTAMPADD(SQL_TSI_MONTH, 1, TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)) 

From right to left the first TIMESTAMPADD returns the first day of the Current Month. The second TIMESTAMPADD then adds one month from the first day of the Current Month arriving to the First Day of the next month.
 

First Day of Current Quarter 
TIMESTAMPADD( SQL_TSI_DAY , DAY_OF_QUARTER( CURRENT_DATE) * -(1) + 1, CURRENT_DATE) 

This was included to show the calculations discussed above can be used with other functions. This is the same expression as the one that returns the first day of the current month except this one uses the DAY_OF_QUARTER property to return the first day of the current quarter.
 

Last Day of the Previous Month 
TIMESTAMPADD( SQL_TSI_DAY , -(1), TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)) 

From right to left the first TIMESTAMPADD returns the first day of the Current Month. The second TIMESTAMPADD subtracts a month to arrive at the first day of the previous month.
 

Last Day of Current Month 

TIMESTAMPADD( SQL_TSI_DAY , -(1), TIMESTAMPADD( SQL_TSI_MONTH , 1, TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE))) 

From right to left the first TIMESTAMPADD finds the first day of the current Month. The second TIMESTAMPADD adds one month to the date to arrive at the first day of the next month. The final TIMESTAMPADD subtracts one day from the returned date to arrive at the last day of the Current Month.
 

Last Day of the Next Month 
TIMESTAMPADD( SQL_TSI_DAY , -(1), TIMESTAMPADD( SQL_TSI_MONTH , 2, TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)))

 From right to left the first TIMESTAMPADD finds the first day of the current Month. The second TIMESTAMPADD adds two months to the date to arrive at the first day of month after next. The final TIMESTAMPADD subtracts one day from the returned date to arrive at the last day of the Next Month.
 

Last Day of Previous Year 

TIMESTAMPADD( SQL_TSI_DAY , -1, TIMESTAMPADD( SQL_TSI_DAY , EXTRACT( DAY_OF_YEAR FROM CURRENT_DATE) * -(1) + 1,
CURRENT_DATE)) 


From right to left the first TIMESTAMPADD returns the first day of the current year. The second TIMESTAMPADD subtracts one day to arrive at December 31st of the previous year.
 

Last Day of Current Year 
TIMESTAMPADD(SQL_TSI_YEAR, 1, TIMESTAMPADD( SQL_TSI_DAY , -1, TIMESTAMPADD( SQL_TSI_DAY , EXTRACT( DAY_OF_YEAR FROM CURRENT_DATE) * -(1) + 1, CURRENT_DATE))) From right to left the first TIMESTAMPADD returns the first day of the current year. The second TIMESTAMPADD deducts one day to arrive at December 31 of the previous year. The third TIMESTAMPADD adds a single year to the date to arrive at December 31 of the Current Year.
 

Last Day of the Next Year 
TIMESTAMPADD(SQL_TSI_YEAR, 2, TIMESTAMPADD( SQL_TSI_DAY , -1, TIMESTAMPADD( SQL_TSI_DAY , EXTRACT( DAY_OF_YEAR FROM CURRENT_DATE) * -(1) + 1, CURRENT_DATE)))

 From right to left the first TIMESTAMPADD returns the first day of the current year. The second TIMESTAMPADD deducts one day to arrive at December 31 of the previous year. The third TIMESTAMPADD adds 2 years to the date to arrive at December 31 of the Next Year.

Last Day of Current Quarter


TIMESTAMPADD( SQL_TSI_DAY , -(1), TIMESTAMPADD( SQL_TSI_QUARTER , 1, TIMESTAMPADD( SQL_TSI_DAY , DAY_OF_QUARTER( CURRENT_DATE) * -(1) + 1, CURRENT_DATE))) 


Demonstrated using Quarters. From right to left the first TIMESTAMPADD returns the first day of the Current Quarter. The second TIMESTAMPADD returns the first day of the next quarter. The final TIMESTAMPADD subtracts a single day from the date to arrive at the last day of the Current Quarter.
 

Number of days between First Day of Year and Last Day of Current Month

 TIMESTAMPDIFF(SQL_TSI_DAY, CAST('2010/01/01 00:00:00' AS DATE), TIMESTAMPADD( SQL_TSI_DAY , -(1), TIMESTAMPADD( SQL_TSI_MONTH , 1, TIMESTAMPADD( SQL_TSI_DAY , DAYOFMONTH( CURRENT_DATE) * -(1) + 1, CURRENT_DATE)))) 

For simplicity I hard coded the January 1, 2010 date and CAST it to a date. I could have used the First Day of the Current Year calculation but didn’t want to over clutter the example. The second part of the TIMESTAMPDIFF uses Last Day of the Current Month calculation to force the TIMESTAMPDIFF to calculate the number of days between the first day of the year and the last day of the current month. 






keywords: obiee 10g, answers, prompt, presentation variables, first day last month combinations, repository variables, 

4 comments:

  1. I have some useful DB scripts in my collection above a look here -- uses full DB scripts

    ReplyDelete
  2. HI, how would I go about filtering the 1st day of each month for a 12 month period - our day field is in date format. I need to know how many employees we had on the 1st day of eevry month for the last 12 years.
    Thanks
    Louis

    ReplyDelete
  3. Great article, exactly what I needed. Thank you!

    ReplyDelete
  4. Thank you for sharing all these formulas. You saved the day.

    I am pretty new to SQL and OBIEE but I simplified the formula for the last day of last month from yours. I want to ask if you see a problem with this formula that I don't see. It seems to work when I try it out just now. Kinda of nervous because I haven't done a lot of OBIEE SQL and don't want it to cause a problem later on.

    (TIMESTAMPADD( SQL_TSI_DAY , (DAYOFMONTH(CURRENT_DATE) * -(1)), CURRENT_DATE)))

    ReplyDelete