There are many things that can help make this world a better place. A pure SQL-based Gantt-chart is not one of them. However, that is exactly what this article will present to you. So you might as well skip it.
Here's the deal: with a data set that represents tasks, events, memberships, worldrecords, job position or anything at all that has a startdate and an enddate, presentation in a Gantt-chart may be useful, to get a good insight in the relative ordering and length of these periods. A Gantt-chart displays all periods as horizontal bars, parallel to the time-axis. In SQL, that could look like this:
Here is how to create such a useful little chart in SQL.
Let's create a table with data that demands a Gantt-chart for proper display.
create table activities ( label varchar2(100) , start_date date , end_date date ) /
Let's add some data to that table.
insert into activities ( label, start_date, end_date ) values ( 'Functional Analysis' , to_date('12-03-2001','DD-MM-YYYY') , to_date('12-11-2001','DD-MM-YYYY') ) / insert into activities ( label, start_date, end_date ) values ( 'Technical Architecture' , to_date('04-05-2001','DD-MM-YYYY') , to_date('18-08-2002','DD-MM-YYYY') ) / insert into activities ( label, start_date, end_date ) values ( 'Technical Design' , to_date('01-12-2001','DD-MM-YYYY') , to_date('24-06-2002','DD-MM-YYYY') ) / insert into activities ( label, start_date, end_date ) values ( 'Development' , to_date('01-05-2002','DD-MM-YYYY') , to_date('12-10-2003','DD-MM-YYYY') ) / insert into activities ( label, start_date, end_date ) values ( 'Acceptance Test' , to_date('10-09-2003','DD-MM-YYYY') , to_date('22-03-2004','DD-MM-YYYY') ) /
And now for a little SQL query that returns the chart:
with periods as ( select label , start_date , end_date from activities ) , limits as -- determine the earliest starting date and the latest end date to determine the overall width of the chart ( select min(start_date) period_start , max(end_date) period_end , 80 width -- set the width as the number of characters from periods ) , bars as ( select lpad(label, '20')||'|' activity , (start_date - period_start)/(period_end - period_start) * width from_pos -- the starting position for the bar , (end_date - period_start)/(period_end - period_start) * width to_pos -- the end position for the bar from periods , limits ) select activity|| lpad('I',from_pos) ||rpad('-', to_pos - from_pos, '-') ||'I' gantt from bars union all select rpad('_',width + 22,'_') from limits union all select lpad('|',21) ||to_char(period_start,'DD-MON-YYYY') ||lpad(to_char(period_end,'DD-MON-YYYY'), width - 11) from limits /
Note: only the very first in-line (view) query is specific for the data set, the other inline views are generic for the Gantt-chart.
Employee Historical Records
Let's take a look at another example: the EMP table in the venerate SCOTT schema. I have slightly manipulated this table, to be able to show the job history for all employees. First I have added the column firedate:
alter table emp add (firedate date) /
then I have randomly set the firedate, to reflect the whimsical nature of our president – who even sacked himself:
update emp set firedate = hiredate + 500 * (1.1 - dbms_random.value) /
The query to produce the Gantt-chart is almost the same as before, only the first in-line view is different:
with periods as ( select ename label , hiredate start_date , firedate end_date from emp order by hiredate ) , limits as ( select min(start_date) period_start , max(end_date) period_end , 80 width from periods ) , bars as ( select lpad(label, '20')||'|' activity , (start_date - period_start)/(period_end - period_start) * width from_pos , (end_date - period_start)/(period_end - period_start) * width to_pos from periods , limits ) select activity|| lpad('I',from_pos) ||rpad('-', to_pos - from_pos, '-') ||'I' gantt from bars union all select rpad('_',width + 22,'_') from limits union all select lpad('|',21) ||to_char(period_start,'DD-MON-YYYY') ||lpad(to_char(period_end,'DD-MON-YYYY'), width - 11) from limits /
Next steps
For next steps we could look at day or week agendas with activities lasting only a few hours or less. And activities that repeat, have more than once instance. And at better axis-markers, showing the date-lables vertically instead of horizontally and not just beginning and end-date or time.
Sorry to be so late in responding to this blog entry.. However, how hard would you think it would be to change the coding to be a resource gantt chart?
Â
Having resources on the X axis and having the name of an user using the resource displayed on the Y axis?
Thank you,
Tony Miller
LuvMuffin Software
Â
Je blijft me verbazen. Cool!
Groeten
—erik
Hi there,
I wold love to try this query out but the whole page appears to be broken .. 🙁
Cheers,
Susanne
I liked the pie chart query better 😉
Wizardry.
Hope you’ll enjoy JavaOne
Really nice query!
Patrick
I will be using this query a lot in the near future, as we have a lot of timelines in our datamodel. Mainly to visualize whether or not there are gaps in the timelines, which in most cases should not be present. I rank this query on the same level with the one Marco Gralike and Tom Kyte mentioned last week http://technology.amis.nl/blog/?p=1882
SQL can be a real help for project managers 🙂