Skip to content

Instantly share code, notes, and snippets.

@craibuc
Last active January 28, 2016 22:22
Show Gist options
  • Save craibuc/919240ee63aec926f627 to your computer and use it in GitHub Desktop.
Save craibuc/919240ee63aec926f627 to your computer and use it in GitHub Desktop.
Generate timespans that can used in place of UNIONs when working with dates.
/*
Author: Craig Buchanan
Purpose: Generate timespans (date ranges); timespans are aligned with monthly boundaries
Parameters:
:periods - number of timespans to generate
:length - length of each timespan, in months
:offset - spacing between timespans, in months
:ending_on - the most-recent timespan should end on this date; supports date strings (e.g. '12/31/2015') and symbolic values (e.g. 'ME-1')
Revisions:
01/05/16 - CB - created
01/27/16 - CB - added ending_on parameter; refactored code to support ending_on parameter
01/28/16 - CB - refactored to consolidate parameters
*/
WITH
Timespan AS (
SELECT to_char(PERIOD_START,'MM/DD/YY') || ' - ' || to_char(PERIOD_END, 'MM/DD/YY') TIMESPAN
,PERIOD_START,PERIOD_END
,calendar_dt
,v.PERIODS,v.LENGTH,v.OFFSET,v.ENDING_ON
FROM (
SELECT add_months( trunc((SELECT efn_din(ending_on) FROM dual),'MONTH'), -(((level-1) * offset)+length)+1 ) PERIOD_START
,add_months( (SELECT efn_din(ending_on) FROM dual), -((level-1) * offset) ) + (86399/86400) PERIOD_END
,p.*
FROM (
SELECT :periods PERIODS
,:length LENGTH
,:offset OFFSET
,:ending_on ENDING_ON
FROM dual
) p
CONNECT BY LEVEL <= PERIODS
) v
)
SELECT * FROM timespan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment