oracle 月分组-获取每个月的计数

llycmphe  于 2023-08-03  发布在  Oracle
关注(0)|答案(5)|浏览(111)

希望得到记录计数为每个月。但是,几个月没有记录,因此不返回行。我怎么能得到那个月的计数为0?

select months, count(rowid) as counter from (
    select  to_char(date_entered, 'MM') as months
    from mydatatable
    where to_char(date_entered, 'yyyy') = '2011'
     )
group by months
order by months

字符串
测试结果:

Month    Count
01       32
03       12
04       11
06       10
07       222
08       32


甚至试着玩subq select 1,2,3,4,5,6,7,8,9,10,11,12 from dual,也无法让它工作。还没有pivot功能...;(

4szc88ey

4szc88ey1#

你可能最好将01到12存储在一个表中,但一般的方法是使用左连接:

Select
  m.Mo,
  Count(t.dateentered)
From (
    Select '01' As Mo From Dual Union All
    Select '02' From Dual Union All
    Select '03' From Dual Union All
    Select '04' From Dual Union All
    Select '05' From Dual Union All
    Select '06' From Dual Union All
    Select '07' From Dual Union All
    Select '08' From Dual Union All
    Select '09' From Dual Union All
    Select '10' From Dual Union All
    Select '11' From Dual Union All
    Select '12' From Dual
  ) m
    Left Outer Join
  mydatatable t
    On
      m.Mo = to_char(t.dateentered, 'MM') And 
      t.dateentered >= DATE'2011-01-01' And
      t.dateentered < DATE'2012-01-01'
Group By
  m.Mo
Order By
  m.Mo

字符串
更新使用了一种更友好的索引方式来限制年份。
http://sqlfiddle.com/#!4/68085/10

wnvonmuf

wnvonmuf2#

您需要构建自己的12行月份“表”并执行左外连接。从您的问题中提取查询,并使其成为提供数据的内联视图。

SELECT m.month "Month", nvl(md.data, 0) "Count"
FROM
(
   select '01' month from dual union all
   select '02' month from dual union all
   select '03' month from dual union all
   select '04' month from dual union all
   select '05' month from dual union all
   select '06' month from dual union all
   select '07' month from dual union all
   select '08' month from dual union all
   select '09' month from dual union all
   select '10' month from dual union all
   select '11' month from dual union all
   select '12' month from dual
) m LEFT OUTER JOIN (
   /* Your Query Here */
) md ON m.month = md.month
ORDER BY m.month;

字符串
结果应该是这样的:

Month       Count
------ ----------
01             32
02              0
03             12
04             11
05              0
06             10
07            222
08             32
09              0
10              0
11              0
12              0

h5qlskok

h5qlskok3#

您可以使用分层查询的connect by语法构建一个包含月份数字的虚拟表,然后左连接到您的数据:

with months as (
    select to_char(level, 'FM00') as month
    from dual
    connect by level <= 12
)
select m.month,
    count(mdt.rowid) as counter
from months m
left join mydatatable mdt
    on mdt.date_entered >= to_date('01/' || m.month || '/2011', 'DD/MM/YYYY')
    and mdt.date_entered <
        add_months(to_date('01/' || m.month || '/2011', 'DD/MM/YYYY'), 1)
group by m.month
order by m.month;

字符串
一些数据:

create table mydatatable (date_entered date, dummy number);
insert into mydatatable values (date '2011-06-02', 0);
insert into mydatatable values (date '2011-07-01', 0);
insert into mydatatable values (date '2011-10-01', 0);
insert into mydatatable values (date '2011-10-31', 0);
insert into mydatatable values (date '2011-11-01', 0);


...这给出:

MONTH COUNTER
----- -------
01          0 
02          0 
03          0 
04          0 
05          0 
06          1 
07          1 
08          0 
09          0 
10          2 
11          1 
12          0


或者SQL Fiddle,因为这似乎是这些天要做的事情...
通常最好避免类似to_char(date_entered, 'yyyy') = '2011'的东西,因为您将to_char()函数应用于表中的每一行,如果该列上有索引,则不会使用它。相反,尝试转换筛选器以匹配列的数据类型,如date_entered > date '2011-01-01' and date_entered < date '2012-01-01'。在这种情况下,它可以在连接条件中处理-我将每个月转换为2011年的日期范围,并且只在该月份范围内查找匹配的记录。

oxalkeyp

oxalkeyp4#

这很奇怪。。也许我误解了问题或数据...?在问题中添加表格和数据总是一个好主意。您应该通过计数获取所有月份的所有数据。我试过这个:

SELECT * FROM stack_test
/
CURR_MONTH  VAL
---------------
01          10
02          15
03          20
04  
05

字符串
正如你所看到的,第4和第5个月没有值:

SELECT months, COUNT(rowid) counter 
   FROM
    (
     SELECT curr_month months
       FROM stack_test
    )
 GROUP BY months
 ORDER BY months
 /
 MONTHS COUNTER
 -------------------
 01           1
 02           1
 03           1
 04           1
 05           1


再举个例子:第2个月没有值,但我仍然可以计数。也许你需要总结一下你的价值观……:

SELECT mth, SUM(val) total_sum, Count(*) total_cnt 
  FROM 
  (
  SELECT mth, (CASE WHEN Mth = '01' THEN '10' ELSE '0' END) val
    FROM
    ( -- Annual table - replace 2 with 12 in Add_Months for the whole year -- 
     SELECT Trunc(SYSDATE,'Y')+Level-1 Curr_Year_By_Date
        , To_char(Trunc(SYSDATE, 'MM') + Rownum-1, 'MM' ) Mth
     FROM dual
    CONNECT BY Level <= Add_Months(Trunc(SYSDATE,'Y'),2)-Trunc(SYSDATE,'Y')
   )
  )
 GROUP BY mth
 ORDER BY 1
 /
 MTH    TOTAL_SUM   TOTAL_CNT
 -------------------------------------
 01         310         31
 02         0           28

tvmytwxo

tvmytwxo5#

这是我的示例,其中DAT_ULT_ALT类似于更新日期:
SELECT TO_CHAR(TMP_ULT_ALT,'YYYY-MM')输入,计数(*)FROM表组输入顺序1

相关问题