Oracle选择查询,分配标签的频率

时间:2014-01-29 22:37:00

标签: sql oracle

如果我知道我收到了多少数据,我可以用这种方式分发标签的外观:

select 
  value_column
, CASE WHEN TO_CHAR(VALUE_DATE, 'mm') = '01' and MOD(extract(year from VALUE_DATE), 3) = 0
    THEN TO_CHAR(VALUE_DATE, 'MON-yyyy') 
    else ' '
    END VALUE_DATE_STRING
from SomeTable

这将显示每三年一月的数据标签。

enter image description here

现在,如果我不知道要回来多少年,我想在同一个选项中计算出来并显示总共5个标签。

我估计我需要这样的东西(伪代码):

CASE WHEN MOD(allRows / 5, ROW_NUM) = 0

我认为唯一具有挑战性的部分是将allRows放在同一个选择中..因为我从telerik报告中调用这个sql,对声明变量并运行多个语句的支持有限..

2 个答案:

答案 0 :(得分:0)

这可能会做你想要的:

select value_column,
       (CASE WHEN mod(rownum, trunc(cnt / 5)) = 0 o
             THEN TO_CHAR(VALUE_DATE, 'MON-yyyy') 
             else ' '
        END) as VALUE_DATE_STRING
from (select t.*, count(*) over () as cnt
      from SomeTable t
     ) t;

可能是trunc((cnt - 1) / 5)

DIT:

如果这样做你想要的,你不需要CTE或子查询。我只是认为这种方式更有意义(并且子查询不会影响性能)。你可以这样做:

select value_column,
       (CASE WHEN mod(row_number() over (order by value_date),
                      trunc(count(*) over () / 5)) = 0
             THEN TO_CHAR(VALUE_DATE, 'MON-yyyy') 
             else ' '
        END) as VALUE_DATE_STRING
from SomeTable t;

顺便说一下,如果您使用的是order by,则应该包含rownum。 Oracle不保证在没有order by的情况下对结果集中的行进行排序。

答案 1 :(得分:0)

这是我的解决方案..它仍然可以优化,我相信四舍五入并不总是对我有利..

WITH base as ( 
    select 
      value_column
    , value_date
    , cnt.c
    , case mod(c,2) when 0 then 6 else 5 end as divider -- get 5 or 6 dates.. try to minimize truncation consequences.. this may need work. 
    , row_number() over (order by value_date) as row_number
    from MyView
    left join (select count(*) c from MyView where id = 250170) cnt on 1=1
    where id = 250170 
    order by value_date
)
select 
      value_column
    , value_date
    , CASE WHEN MOD(row_number, trunc(c/divider)) = 0
        THEN TO_CHAR(VALUE_DATE, 'MON-yyyy') 
        else ' '
        END VALUE_DATE_STRING
from base
order by value_date

<强>更新

根据戈登的回答简化

select 
      value_column
    , value_date
    , (
        CASE WHEN 
            mod(
                row_number() over (order by value_date), 
                trunc(count(*) over () / 5)) = 0
        THEN TO_CHAR(VALUE_DATE, 'MON-yyyy') 
        else ' '
        END) as LABEL_STRING

from MyView