Grouping by week using Date column

I have a table with a date column. I'd like to generate a report grouping all entries by week. Is this possible with the date expressions/functions within Oracle?
Thanks

What is your definition of a week?
select to_char(sysdate, 'IW') from dual
will return 21 which is the week of the year according to the ISO standard
So a query such as
SELECT TO_CHAR(mydate, 'IW'), col1, col2
FROM mytable
GROUP BY TO_CHAR(mydate, 'IW')
will group the data by the ISO week.
You may also want to select the year as part of the query.
null

Similar Messages

  • Grouping Via Week Ending Date

    Hi All,
    I have transaction line data for each day for our customer and i would like to group via Week Ending date.  Our week runs from Sunday to Saturday.
    If i Add the transaction date to the group expert it allows me to group via week(perfect) but does it via week commencing.  I see you can group via formula, does any one know how you can get the grouping via Week Ending.
    thanks for any help and advise.
    mike

    Try using this formula...
    DateAdd("ww", DateDiff("ww", #1/6/1900#, {TableName.DateField}), #1/6/1900#)
    This formula will calculate the "Following Saturday" for any given date. If the date supplied is a Saturday, it will return that same date.
    So...
    11/2/2010 > 11/6/2010
    11/13/2010 > 11/13/2010
    11/14/2010 > 11/20/2010
    HTH,
    Jason

  • Group by week between date range

    Hi,
    i'm having a table for documents. The documents are received from diffeent dates. I've to calculate number of documents received on weekly basis.
    I need an sql to count the number of documents between two given dates grouping by weekly.
    My week starts on Sunday and ends with Saturday.
    I've tried group by with to_char(documentdate,'IW') , but this will take Monday to Sunday as a week & the incomlete weeks i'm not able to calculate. ie : in the below output the date range 1/28/2007 - 1/31/2007 is not a complete week . ( ie saturday to wednesday)
    I need out put should be like this for Date Range: 12/31/2006 to 1/31/2007
    week               count of documents
    12/31/2006 - 1/6/2007 10
    1/7/2007 - 1/13/2007     40
    1/14/2007 - 1/20/2007     30
    1/21/2007 - 1/27/2007     20
    1/28/2007 - 1/31/2007 10
    Please help me to get this.....
    (columns in documents table is documentid and documentdate)

    your're very close with IW. you just need to shift the data to get it to fall within the correct range. btw, you don't need julian dates. it's overkill
    trunc(date+1,'IW') will push the date into the correct week range (IW will put sunday one week earlier than you want, so push it ahead a day before truncating).
    then subtract 1 day from the result to get it to display with sunday's date instead of monday
    trunc(mydate+1, 'IW')-1
    and the week end date is simply trunc(mydate+1, 'IW')_5
    select mydate, to_char(mydate,'Dy') dy,
    trunc(mydate+1,'IW')-1 wk_Start,
    trunc(mydate+1,'IW')+5 wk_end
    from (select sysdate-rownum mydate from dual connect by level < 20)
    order by 1

  • How to use date column index

    Hi,
    Why is that I got different results for my queries?
    Note that emp_date is indexed, so i dont want to use
    a function to it.
    QUERY1(full table scan)
    SELECT COUNT(*) FROM EMP WHERE TRUNC(EMP_DATE)=TRUNC(SYSDATE-30); (RESULT=8,842)
    QUERY2
    SELECT COUNT(*) FROM EMP WHERE
    EMP_DATE >=(SYSDATE-30) and EMP_DATE < (SYSDATE-30); (RESULT=0)
    QUERY3
    SELECT COUNT(*) FROM EMP WHERE
    EMP_DATE BETWEEN TRUNC(SYSDATE-30) and TRUNC(SYSDATE-30); (RESULT=2,100)
    Please help me how to use indexed date column...

    > Why is that I got different results for my queries?
    Because your queries are different.
    1) This one selects all records on 20 october, regardless of their time component
    2) This one selects all records with an emp_date at least being 20 october 14:56:30 AND being smaller than 20 october 14:56:30. No record will ever satisfy this condition.
    3) This one selects all records on 19./20 october at midnight 00:00:00
    Please see this example:
    SQL> create table myemp (emp_date)
      2  as
      3   select trunc(sysdate) - 30 +
      4          case
      5          when level <= 2100 then 0
      6          when level <= 8842 then dbms_random.value(1,86399)/86400
      7          else 2
      8          end
      9     from dual
    10  connect by level <= 100000
    11  /
    Tabel is aangemaakt.
    SQL> create index i1 on myemp(emp_date)
      2  /
    Index is aangemaakt.
    SQL> exec dbms_stats.gather_table_stats(user,'myemp',cascade=>true)
    PL/SQL-procedure is geslaagd.
    SQL> set autotrace on explain
    SQL> select count(*) from myemp where trunc(emp_date)=trunc(sysdate-30)
      2  /
                                  COUNT(*)
                                      8842
    1 rij is geselecteerd.
    Uitvoeringspan
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=88 Card=1 Bytes=8)
       1    0   SORT (AGGREGATE)
       2    1     TABLE ACCESS (FULL) OF 'MYEMP' (Cost=88 Card=1000 Bytes=
              8000)
    SQL> select count(*) from myemp where
      2  emp_date >=(sysdate-30) and emp_date < (sysdate-30)
      3  /
                                  COUNT(*)
                                         0
    1 rij is geselecteerd.
    Uitvoeringspan
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=8)
       1    0   SORT (AGGREGATE)
       2    1     FILTER
       3    2       INDEX (RANGE SCAN) OF 'I1' (NON-UNIQUE) (Cost=4 Card=2
              50 Bytes=2000)
    SQL> select count(*) from myemp where
      2  emp_date between trunc(sysdate-30) and trunc(sysdate-30)
      3  /
                                  COUNT(*)
                                      2100
    1 rij is geselecteerd.
    Uitvoeringspan
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=8)
       1    0   SORT (AGGREGATE)
       2    1     FILTER
       3    2       INDEX (RANGE SCAN) OF 'I1' (NON-UNIQUE) (Cost=4 Card=2
              50 Bytes=2000)
    > Please help me how to use indexed date column...
    Use this query instead:
    SQL> select count(*)
      2    from myemp
      3   where emp_date between trunc(sysdate)-30 and trunc(sysdate)-29 - interval '1' second
      4  /
                                  COUNT(*)
                                      8842
    1 rij is geselecteerd.
    Uitvoeringspan
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=8)
       1    0   SORT (AGGREGATE)
       2    1     FILTER
       3    2       INDEX (RANGE SCAN) OF 'I1' (NON-UNIQUE) (Cost=4 Card=2
              50 Bytes=2000)Regards,
    Rob.

  • Hi in the between operator how to use date column

    Hi
    I have one small doubut ,once i try to get the results perticular between dates ,it not working
    ex:- in the emp table i try get the employess u hire between 01-jan-80 to 03-jan-80
    once i use query select * from emp where hiredate between '01-jan-80' and '03-jan-80'
    it is display differnt data.
    plz help i want data only 01,2nd and 3rd jan data only how to write query.
    Thank's

    Hi,
    When you want to hard-code a DATE, don't just use a string. Use the TO_DATE function, for example
    TO_DATE ( '01-jan-1980'
            , 'dd-mon-yyyy'
            )or use a DATE literal (always specified in 'YYYY-MM-DD' format):
    DATE '1980-01-01'Remember that DATE expressions always include the time of day. If you use TO_DATE without specifying the time, or a DATE literal (as I did above) the time defaults to midnight, which is the first point in time on that day.
    If you are certain that your all DATEs in your table are at midnight, you can use BETWEEN like this:
    select  *
    from      emp
    where      hiredate between TO_DATE ('01-jan-1980', 'dd-mon-yyyy')
               and       TO_DATE ('03-jan-1980', 'dd-mon-yyyy')
    ;If your table did have a hiredate such as January 3, 1980, 10:35 am, the query above would not choose it (because 10:35 is later than midnight.)
    Because of the problems with BETWEEN, some people do two comparisons instead:
    select  *
    from      emp
    where      hiredate >= TO_DATE ('01-jan-1980', 'dd-mon-yyyy')
    and      hiredate <  TO_DATE ('03-jan-1980', 'dd-mon-yyyy') + 1
    ;This will pick anything on January 3, 1980, regardless of its time.
    Edited by: Frank Kulash on Aug 5, 2009 10:49 AM

  • Using number datatype for date column

    Hi
    Is there a side effect for using "number" datatype for "date" column?
    If so, what is the disadvantage?
    Many thanks

    Hi,
    Ora_83 wrote:
    Hi
    Is there a side effect for using "number" datatype for "date" column?
    If so, what is the disadvantage?Yes, there's a definite disadvantage.
    Oracle provides date arithmetic and a number of functions for manipulating DATEs. None of them work with numbers.
    For example,
    SELECT    TRUNC (order_date, 'MONTH')     AS order_month
    ,       AVG (ship_date - order_date)     AS avg_delay
    FROM       orders
    GROUP BY  TRUNC (order_date, 'MONTH')
    ;order_month involves a DATE function; it's pretty easy to find the month that conatins order_date.
    avg_delay involves date arithmetic. It's extrememly easy to find how much the time passed between order_date and ship_date.
    Depending on how you code dates as numbers, doing either one of the above may be just as easy, but doing the other will be very difficult. You'll waste a lot of effort converting the NUMBERs to real DATEs whenever you need to manipulate them.
    Validation can be very difficult for NUMBERs, also.
    Watch this forum. It's a rare day when there's not some question about how to get around a problem caused by storing dates in a NUMBER (or VARCHAR2) column. Don't add to that. Always use DATE columns for dates.

  • Which type of index is useful for date columns with time stamp

    Hi all,
    I am using date column in the where clause of an SQL Query. The values stored in the date column are includes timestamp. The query is very slow and there is no index on the date column.
    Can any body suggest which index is better on date columns
    Thanks

    I am using date column in the where clause of an SQL Query.Dates a re hard queries to tune. This ...
    WHERE start_date BETWEEN to_date('01-SEP-05') AND to_date('02-SEP-05')...probably requires a very different execution plan to this...
    WHERE start_date BETWEEN to_date('01-JAN-01') AND to_date('02-SEP-05')Just bunging an index on the date column may speed up your specific query but break something else. So be careful.
    Cheers, APC

  • Indexes against Date Columns

    Dear All,
    I am trying to run query and in WHERE clause using DAtes columns but performance is very slow. Can I declares then indexes against date coulmns? If yes what is general formt to create index against Datae column?
    Thanks

    Indexing on the date columns would be similar to other column. You can create normal B Tree index on the desired Date column as usual but before creating, keep track on the unique values for column. This is because if your data is like grouping the data per dates, you can even look for Bitmap index too.
    Hope this works fine for you !!

  • Cross database join Oracle - SQL server date column - nQSError: 46008

    Hi,
    I am using OBIEE 10.1.3.4.2 and
    I am able to make cross database join between Oracle and SQL server using varchar columns, but I am getting this error:
    nQSError:22024-A comparison is being carried out between noncompatible type when I try to make "foreign key" join between two tables (one from Oracle, second from SQL Server) using number columns (INT, DOUBLE...). It is strange, but I when I make "complex join" on physical layer no error is thrown and everything works fine.
    But I am not able to make join between tables using Date column. Column in Oracle table has DATE datatype, column in SQL server tables has datetimeoffset(7) datatype (example: 2011-07-19 13:14:22.2032605 +02:00). So I tried to cast datetimeoffset(7) to date datatype using "convert(DATE,HappenedOn,120)" - this returns me 2011-07-19 . In this format, BI can show converted date column, I can make filter using this date column, but I am not able to make physical join with Oracle table using this column
    Answer using data from both joined tables gives me this error:
    [nQSError: 46008] Internal error: File .\DataType\SUKeyCompare.cpp, line 875. (HY000)
    Do you have some tips, how to solve this "bug"?

    Parse the command column to get the SSIS package file name may be your only option here.

  • Date column group by 15 minute interval using SQL

    I am using Oracle 9i DB, I have a large table containing several rows with following example data. Each row identifies a transaction.
    Transaction_id, status, completed_date
    1667050 SUCCEEDED 4-Dec-03 00:00:44
    1667091 SUCCEEDED 4-Dec-03 00:05:45
    6670930 SUCCEEDED 4-Dec-03 00:09:46
    4359066 SUCCEEDED 4-Dec-03 00:10:46
    this table consists of rows for a 24 hour day period.
    I need to write a SQL query to generate a report to give me a count of transactions 24 hour period grouped into 15 minute or half hour period.
    for example
    count time_interval
    5000 00:00:00 - 00:14:59
    2345 00:15:00 - 00:29:59
    and so on
    I am new to SQL and so am having a hard time figuring out which function or how to group date column to achieve the end result. I would be grateful if someone could throw some suggestions.

    This should help.
    http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:4222062043865

  • Grouping of chracateristics by using dynamic data columns

    Hi all,
    I want to create a BPS Layout (BW3.5) with the material in the lead column and a KeyFigures, the year and the salesgroup in the data column. The salesgroup is the dynamic characteristic.
    Example:
    I want to have:
    SG1 2007/   SG1 2008/   SG2 2007/   SG2 2008...
    What the system is doing is:
    SG1 2007/   SG2 2007/   SG1 2008/   SG2 2008
    My question is: how can I change the grouping of the columns from year to salesorg?
    Can anybody help me?
    Best regards,
    Rainer

    Hi Rainer,
    Thanks for your appreciation.
    I thought there is not material in your lead column, okay if your case like that i suggest you like this.
    I suggest to .
    To choose Layout Category:
    1. Key Figures in Data Column
    Define data column dynamically for : Sales Group
    And make the fiscal year, and material as lead column.
    In the data column tab, define the key-figures there and mark Dynamic checkbox.
    Or if you want to group based on the fiscal year, you can make the fiscal year as you dynamic data column.
    Hopefully it can help you a lot.
    Best regards,
    Niel.
    thanks for the points you choose to assign.

  • Need to show a data in weeks for stacked column

      I need to show the data broken down in weeks if you choose the start date and end date.   I have to show in a stacked column chart. I am trying to show the values if you choose for example last month i need to show it by weeks for example 
    week    user name   total approved first approved    last aprovedDate  totalitemsAdded
    week 1   XYZ                 3                10/01/2012       10/05/2012         5
    week2   XYZ                  5                 etc                      etc            
      etc
    week 3 
    Below is the code and the result  i am getting now . 
    Current Results
    UserName TotalApproved
    FirstApprovedDate LastApprovedDate
       TotalItemsAdded
    XYZ            9
               2011-11-19 16:56:49.960
         2011-11-19 18:18:20.783
                   2
    DECLARE @StartDate DATETIME
    DECLARE @EndDate DATETIME
    SET @StartDate = '10/1/2012 '
    SET @EndDate = '10/31/2012'
    ;with Items as(
           SELECT
                  UserName = Profile.Description,
                  TotalItems = COUNT(TransactionID),
                  FirstAddedDate = MIN(UTCDate),
                  LastAddedDate = MAX(UTCDate)
           FROM Transactiondatabase.dbo.transaction
                    JOIN Biography.dbo.Profile ON transaction.ProfileId = Profile.ProfileID
           WHERE 
                  Data like '%ItemAdded%'
                    AND UTCDate BETWEEN @StartDate AND DATEADD(dd,1,@EndDate)
           GROUP BY
                  Profile.Description 
    Approved as
           SELECT 
                  UserName = Profile.Description,
                  TotalApproved = COUNT(TransactionID),
                  FirstApprovedDate = MIN(UTCDate),--Demo
                  LastApprovedDate = MAX(UTCDate)                 
           FROM Transactiondatabase..transaction
                    JOIN Biography.dbo.Profile ON transaction.ProfileId = Profile.ProfileID
           WHERE 
                  Data like '%Approved%'
                    AND UTCDate BETWEEN @StartDate AND DATEADD(dd,1,@EndDate)
           GROUP BY
                    Profile.Description
    Select Distinct Approved.*, TotalItemssAdded = sum(distinct Items.TotalItems)
    from Items, Approved  
    Group by Approved.UserName, Approved.FirstApprovedDate, Approved.LastApprovedDate, Approved.TotalApproved
    using ssrs 2005 

    Hi Sunny04,
    If I understand correctly, you want to display the data by weeks in a stacked column chart. If in this case, we can add a calculated field named week to display the week name, and then group it. For more details, please see the following steps:
    Right-click the dataset to add a calculated field with the values below:
    Name: Week
    Calculated field: =DatePart(DateInterval.WeekOfYear,Fields!FirstApprovedDate.Value,0,0)
    Add Week field to category group area in a stacked column chart.
    Right-click Week field to open the Properties dialog box, modify the expression of Label to like this:
    ="week"&Fields!Week.Value
    Add TotalApproved or TotalItemsAdded field to data area in the chart.
    If there are any misunderstanding, please elaborate the issue for further investigation.
    Thanks,
    Katherine Xiong
    Katherine Xiong
    TechNet Community Support

  • Group data by week of data filter in ssrs

    Hii all
    I am creating matrix report  where report has date parameters like @From_Date and @To_Date
    and more, i want to provide a filter like selection : where user will select Weekly, Mothly or Daily
    I would do it with grouping based expreession on primary group of report ,
    when user select daily , i just group on my date field when user select yearly i have  puted a expression to format a date to year but i dont know how to do it for weeks
    well i want like Week1 , Week2 , week3 and Week 4 or (Week 5 if) week wise data 
    Help would be appreciated !
    Dilip Patil..

    Hi Dilip Patil,
    According to your description, you want to group the data based on the parameter selection. Right?
    In this scenario, it seems you only have a date column. We can use datepart() function to get the Year, Month, Week, Day from the date column. Then use the Switch() function in Group Expression to have the records group on the parameter selection. Please refer
    to the Group Expression below:
    =Switch(Parameter!param="day",DatePart(DateInterval.Day,Fields!DateCol.Value),
    Parameter!param="week",DatePart(DateInterval.WeekOfYear,Fields!DateCol.Value),
    Parameter!param="month",DatePart(DateInterval.Month,Fields!DateCol.Value),
    Parameter!param="year",DatePart(DateInterval.Year,Fields!DateCol.Value))
    If you have any question, please feel free to ask.
    Best Regards,
    Simon Hou

  • Week and month calculation from date column

    I have 3 column data like
    with tab as
      select 'Topshop' brand, '10-JUL-11' deliverydate, '100' qty from dual union all
      select 'Topshop' brand, '10-JUL-11' deliverydate, '400' qty from dual union all
      select 'NewSita' brand, '11-JUL-11' deliverydate, '200' qty from dual union all
      select 'LaGress' brand, '12-JUL-11' deliverydate, '300' qty from dual union all
      select 'LaGress' brand, '10-AUG-11' deliverydate, '100' qty from dual union all
      select 'LaGress' brand, '11-AUG-11' deliverydate, '200' qty from dual union all
      select 'Topshop' brand, '12-AUG-11' deliverydate, '300' qty from dual union all
      select 'NewSita' brand, '10-SEP-11' deliverydate, '100' qty from dual union all
      select 'Topshop' brand, '11-SEP-11' deliverydate, '200' qty from dual union all
      select 'NewSita' brand, '12-SEP-11' deliverydate, '300' qty from dual
    ) select * from tabI need to convert it into 4 columns
    Brand | Month | Week(start date) | Qty (sum)
    Please let me know what are the options that i have, especially the date-time calculation functions available to solve such problems.
    Thanks
    w\

    with tab as
      select 'Topshop' brand, to_date('10-JUL-11', 'dd-mon-yy') deliverydate, '100' qty from dual union all
      select 'Topshop' brand, to_date('10-JUL-11', 'dd-mon-yy') deliverydate, '400' qty from dual union all
      select 'NewSita' brand, to_date('11-JUL-11', 'dd-mon-yy') deliverydate, '200' qty from dual union all
      select 'LaGress' brand, to_date('12-JUL-11', 'dd-mon-yy') deliverydate, '300' qty from dual union all
      select 'LaGress' brand, to_date('10-AUG-11', 'dd-mon-yy') deliverydate, '100' qty from dual union all
      select 'LaGress' brand, to_date('11-AUG-11', 'dd-mon-yy') deliverydate, '200' qty from dual union all
      select 'Topshop' brand, to_date('12-AUG-11', 'dd-mon-yy') deliverydate, '300' qty from dual union all
      select 'NewSita' brand, to_date('10-SEP-11', 'dd-mon-yy') deliverydate, '100' qty from dual union all
      select 'Topshop' brand, to_date('11-SEP-11', 'dd-mon-yy') deliverydate, '200' qty from dual union all
      select 'NewSita' brand, to_date('12-SEP-11', 'dd-mon-yy') deliverydate, '300' qty from dual
    ), week_data as (
       select brand
       ,      to_char(deliverydate, 'Month', 'nls_date_language=american') MON
       ,      trunc(deliverydate, 'day') WEEK_START
       ,      sum(TO_NUMBER(qty)) SUM_QTY
       from   tab
       group by brand
       ,      to_char(deliverydate, 'Month', 'nls_date_language=american')
       ,      trunc(deliverydate, 'day')
    ), weeks as (
       select
       w.week_min + (level - 1) * 7 week_start
       from (
          select min(week_start) week_min, max(week_start) week_max
          from week_data
       ) w, dual
       connect by level <= 1 + (w.week_max - w.week_min) / 7
    select
    week_data.brand,
    weeks.week_start,
    nvl(week_data.sum_qty,0) sum_qty
    from week_data
    partition by (brand)
    right outer join weeks
    on (weeks.week_start = week_data.week_start)
    order by
    weeks.week_start,
    week_data.brand;You construct a set of records of all "week_start" dates from your minimum to your maximum (classic connect by level trick.)
    You use a partitioned outer join to fill in the gaps in your sparse data (see doc example [url http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/statements_10002.htm#i2177515]here.
    Hope that helps you :-)
    (PS. I dislike implicit conversions - that is the only reason I have added a TO_NUMBER to your code within the sum() ;-) )
    (PPS. Actually you probably should have asked this in a new question - I believe it is not really good forum etiquette to continue in a thread that has already been answered...)

  • Using MODEL clause and COUNT for not numeric data columns....

    Hi ,
    Is it possible somehow to use the COUNT function to transform a non-numeric data column to a numeric data value (a counter) and be used in a MODEL clause....????
    For example , i tried the following in the emp table of SCOTT dataschema with no desired result...
    SQL> select deptno , empno , hiredate from emp;
    DEPTNO EMPNO HIREDATE
        20  7369 18/12/1980
        30  7499 20/02/1981
        30  7521 22/02/1981
        20  7566 02/04/1981
        30  7654 28/09/1981
        30  7698 01/05/1981
        10  7782 09/06/1981
        20  7788 18/04/1987
        10  7839 17/11/1981
        30  7844 08/09/1981
        20  7876 21/05/1987
        30  7900 03/12/1981
        20  7902 03/12/1981
        10  7934 23/01/1982
    14 rows selected Now , i want to use the MODEL clause in order to 'predict' the number of employees who were going to be hired in the 1990 per deptno...
    So , i have constructed the following query which , as expected, does not return the desired results....
    SQL>   select deptno , month , year , count_
      2    from
      3    (
      4    select deptno , to_number(to_char(hiredate,'mm')) month ,
      5                to_number(to_char(hiredate , 'rrrr')) year , count(ename) count_
      6    from emp
      7    group by  deptno , to_number(to_char(hiredate,'mm'))  ,
      8                to_number(to_char(hiredate , 'rrrr'))
      9    )
    10    model
    11    partition by(deptno)
    12    dimension by (month , year)
    13    measures (count_ )
    14    (
    15     count_[1,1990]=count_[1,1982]+count_[11,1982]
    16    )
    17  /
        DEPTNO      MONTH       YEAR     COUNT_
            30          5       1981          1
            30         12       1981          1
            30          2       1981          2
            30          9       1981          2
            30          1       1990
            20          4       1987          1
            20          5       1987          1
            20          4       1981          1
            20         12       1981          1
            20         12       1980          1
            20          1       1990
            10          6       1981          1
            10         11       1981          1
            10          1       1982          1
            10          1       1990 As you see , the measures for the 1990 year is null...because the measure(the count(deptno)) is computed via the group by and not by the MODEL clause...
    How should i transform the above query... so as the "count_[1,1982]+count_[11,1982]" will return non-null results per deptno...????
    Thanks , a lot
    Simon

    Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
    Connected as hr
    SQL>
    SQL> SELECT department_id, MONTH, YEAR, count_
      2    FROM (SELECT e.department_id
      3                ,to_number(to_char(e.hire_date, 'mm')) MONTH
      4                ,to_number(to_char(e.hire_date, 'rrrr')) YEAR
      5                ,COUNT(e.first_name) count_
      6            FROM employees e
      7            WHERE e.department_id = 20
      8           GROUP BY e.department_id
      9                   ,to_number(to_char(e.hire_date, 'mm'))
    10                   ,to_number(to_char(e.hire_date, 'rrrr')));
    DEPARTMENT_ID      MONTH       YEAR     COUNT_
               20          8       1997          1
               20          2       1996          1
    SQL> --
    SQL> SELECT department_id, MONTH, YEAR, count_
      2    FROM (SELECT e.department_id
      3                ,to_number(to_char(e.hire_date, 'mm')) MONTH
      4                ,to_number(to_char(e.hire_date, 'rrrr')) YEAR
      5                ,COUNT(e.first_name) count_
      6            FROM employees e
      7            WHERE e.department_id = 20
      8           GROUP BY e.department_id
      9                   ,to_number(to_char(e.hire_date, 'mm'))
    10                   ,to_number(to_char(e.hire_date, 'rrrr')))
    11  model
    12  PARTITION BY(department_id)
    13  dimension BY(MONTH, YEAR)
    14  measures(count_)(
    15    count_ [1, 1990] = count_ [2, 1996] + count_ [8, 1997]
    16  );
    DEPARTMENT_ID      MONTH       YEAR     COUNT_
               20          8       1997          1
               20          2       1996          1
               20          1       1990          2
    SQL> ---
    SQL> SELECT department_id, MONTH, YEAR, count_
      2    FROM (SELECT e.department_id
      3                ,to_number(to_char(e.hire_date, 'mm')) MONTH
      4                ,to_number(to_char(e.hire_date, 'rrrr')) YEAR
      5                ,COUNT(e.first_name) count_
      6            FROM employees e
      7           GROUP BY e.department_id
      8                   ,to_number(to_char(e.hire_date, 'mm'))
      9                   ,to_number(to_char(e.hire_date, 'rrrr')))
    10  model ignore nav
    11  PARTITION BY(department_id)
    12  dimension BY(MONTH, YEAR)
    13  measures(count_)(
    14    count_ [1, 1990] = count_ [2, 1996] + count_ [8, 1997]
    15  );
    DEPARTMENT_ID      MONTH       YEAR     COUNT_
              100          8       1994          2
               30         12       1997          1
              100          3       1998          1
               30          7       1997          1
                           5       1999          1
               30         12       1994          1
               30         11       1998          1
               30          5       1995          1
              100          9       1997          2
              100         12       1999          1
               30          8       1999          1
                           1       1990          0
               30          1       1990          0
              100          1       1990          0
               90          9       1989          1
               20          8       1997          1
               70          6       1994          1
    93 rows selected
    SQL>

Maybe you are looking for