表A有两个日期字段,分别是A.begin和A.end,当我想统计2009年的记录数时,SQL语句是这么写的:select count(*)
from A a
where to_char(a.begin,'yyyy')<='2009' and to_char(a.end,'yyyy')>'2009'现在从前端传来用户选择的两个年份值,分别是nf1和nf2,nf1小于nf2,例如nf1是2009,nf2是2017,然后需要统计出2009年至2017年每一年的记录数量。用如下形式展示:年份   数量
2009  221
2010  322
2011  732
...
2017  102现在的想法是根据传入的nf1和nf2动态拼接union all来实现,但我不想使用union all,因为这样很影响效率。
union all想法的SQL语句如下(2009年至2011年):select 2009 as 年份, count(*)
from A a
where to_char(a.begin,'yyyy')<='2009' and to_char(a.end,'yyyy')>'2009'
union all
select 2010 as 年份, count(*)
from A a
where to_char(a.begin,'yyyy')<='2010' and to_char(a.end,'yyyy')>'2010'
union all
select 2011 as 年份, count(*)
from A a
where to_char(a.begin,'yyyy')<='2011' and to_char(a.end,'yyyy')>'2011'

解决方案 »

  1.   

    对于跨年的数据,如果按照开始时间来算的话
    select to_char(a.begin, 'yyyy'), count(*)
      from A a
     where to_char(a.begin, 'yyyy') <= 'nf1'
       and to_char(a.end, 'yyyy') > 'nf2'
     group by to_char(a.begin, 'yyyy')
      

  2.   

    统计nf1到nf2所有数据的where应该是【begin<=nf2 and end>nf1】吧。
    刚才想了一下,这个问题的描述可以简化一下,统计2016和2017年的数据,对于【to_char(a.begin,'yyyy')<='nf' and to_char(a.end,'yyyy')>'nf'】这样的条件,表中的记录可能既属于2016年也属于2017年,我可以用【begin<=2017 and end>2016】这个条件统计出2016年和2017年所有的数据,比如有100条,但单独的统计出2016年的再加上2017年的,这个数量肯定是>=100的。在这种情况下根据年份进行分组
      

  3.   

    统计nf1到nf2所有数据的where条件这样写好像也不对
      

  4.   

    ​查询 SELECThttp://www.verejava.com/?id=17173779389953
      

  5.   


    想跨年的数据对于每一年分别统计一次?with tab1 as (
    select 1 id, date'2017-01-01' be, date'2018-01-01' en from dual union all
    select 2 id, date'2015-01-01' be, date'2018-01-01' en from dual union all
    select 3 id, date'2018-01-01' be, date'2018-08-01' en from dual 
    )select count(1), to_char(add_months(be, 12 * (level - 1)), 'yyyy')
      from tab1 t1
    connect by trunc(add_months(be, 12 * (level - 1)), 'y') <= trunc(en, 'y')
           and prior id = id
           and prior dbms_random.value is not null
     group by to_char(add_months(be, 12 * (level - 1)), 'yyyy');