修改查询结果集以包括范围中的所有日期

时间:2012-01-26 00:50:34

标签: oracle groovy

我有一个查询,我在一个表TXN_DEC(id, resourceid, usersid, date, eventdesc)上运行,它返回给定日期范围和resourceid的不同用户数,按日期和eventdesc分组(每个资源可以有4到5个eventdesc)

如果不同用户的值没有计算范围内的日期,则对于eventdesc,它会跳过结果集中的日期行。

我需要在结果集或集合中包含所有日期行,以便如果日期,eventdesc组合没有count值,则其值设置为0但该日期仍存在于集合中。

我如何获得这样的收藏

我知道完全从查询结果中获取最终数据集会太复杂, 但是我可以在groovy中使用集合来修改和填充我的地图/列表以获得所需格式的数据

类似于以下内容:if

  

输入日期范围= 2011年2月5日至3月3日

      DataMap = [dateval: '02/05/2011' eventdesc: 'Read' dist_ucnt: 23,
                 dateval: '02/06/2011' eventdesc: 'Read' dist_ucnt: 23,
                 dateval: '02/07/2011' eventdesc: 'Read' dist_ucnt: 0,  -> this row was not present in query resultset, but row exists in the map with value 0
                 ....and so on till 3 march 2011 and then whole range repeated for each eventdesc
                     ] 

1 个答案:

答案 0 :(得分:1)

如果您想要给定范围内的所有日期(包括TXN_DEC表中没有条目的日期),您可以使用Oracle生成日期范围,然后对现有查询使用外部联接。然后你只需要填写空值。类似的东西:

select 
    d.dateInRange as dateval,
    'Read' as eventdesc,
    nvl(td.dist_ucnt, 0) as dist_ucnt
from (
    select 
        to_date('02-FEB-2011','dd-mon-yyyy') + rownum - 1 as dateInRange
    from all_objects
    where rownum <= to_date('03-MAR-2011','dd-mon-yyyy') - to_date('02-FEB-2011','dd-mon-yyyy') + 1
) d
left join (
    select 
        date,
        count(distinct usersid) as dist_ucnt
    from
        txn_dec
    where eventDesc = 'Read'
    group by date 
) td on td.date = d.dateInRange

这是我纯粹的Oracle解决方案,因为我不是一个Groovy家伙(好吧,实际上,我是一个非常时髦的家伙......)

编辑:这是包装在存储过程中的相同版本。如果你知道API就应该很容易打电话......

create or replace procedure getDateRange (
    p_begin_date IN DATE, 
    p_end_date IN DATE, 
    p_event IN txn_dec.eventDesc%TYPE,
    p_recordset OUT SYS_REFCURSOR)
AS
BEGIN
    OPEN p_recordset FOR
    select 
        d.dateInRange as dateval,
        p_event as eventdesc,
        nvl(td.dist_ucnt, 0) as dist_ucnt
    from (
        select 
            p_begin_date + rownum - 1 as dateInRange
        from all_objects
        where rownum <= p_end_date - p_begin_date + 1
    ) d
    left join (
        select 
            date,
            count(distinct usersid) as dist_ucnt
        from
            txn_dec
        where eventDesc = p_event
        group by date 
    ) td on td.date = d.dateInRange;
END getDateRange;