我有包含调用数据的表,列CALLDATE包含调用的日期和时间。
我需要一个查询,它会返回过去6个月内每个月的来电次数。
结果如下:
PERIOD|CALLS
======|=====
201705|15235
201704|14965
201703| 0 <-- no data for this month
201702|12365
201701|13468
201612|14563
我有以下查询:
SELECT COUNT (*)
FROM mytable
WHERE calldate BETWEEN TRUNC (ADD_MONTHS (SYSDATE, -1), 'MON')
AND TRUNC (ADD_MONTHS (SYSDATE, -0), 'MON')
UNION
SELECT COUNT (*)
FROM mytable
WHERE calldate BETWEEN TRUNC (ADD_MONTHS (SYSDATE, -2), 'MON')
AND TRUNC (ADD_MONTHS (SYSDATE, -1), 'MON')
UNION
SELECT COUNT (*)
FROM mytable
WHERE calldate BETWEEN TRUNC (ADD_MONTHS (SYSDATE, -3), 'MON')
AND TRUNC (ADD_MONTHS (SYSDATE, -2), 'MON')
UNION
SELECT COUNT (*)
FROM mytable
WHERE calldate BETWEEN TRUNC (ADD_MONTHS (SYSDATE, -4), 'MON')
AND TRUNC (ADD_MONTHS (SYSDATE, -3), 'MON')
UNION
SELECT COUNT (*)
FROM mytable
WHERE calldate BETWEEN TRUNC (ADD_MONTHS (SYSDATE, -5), 'MON')
AND TRUNC (ADD_MONTHS (SYSDATE, -4), 'MON')
UNION
SELECT COUNT (*)
FROM mytable
WHERE calldate BETWEEN TRUNC (ADD_MONTHS (SYSDATE, -6), 'MON')
AND TRUNC (ADD_MONTHS (SYSDATE, -5), 'MON')
也许有更简单的解决方案。
答案 0 :(得分:0)
一种方法可能是创建一个月份列表,从sysdate开始到6个月前,并在外表jon方面使用你的表到这个表。 例如:
/* sample data */
with yourTable(callDate) as (
select date '2017-05-15' from dual union all
select date '2017-05-15' from dual union all
select date '2017-04-15' from dual union all
select date '2017-03-15' from dual union all
select date '2017-03-15' from dual union all
select date '2017-02-15' from dual union all
select date '2016-12-15' from dual
)
/* the query */
select count(callDate),
to_char(monthStart, 'yyyymm')
from (
select add_months(trunc(sysdate, 'Month'), -level +1) monthStart,
last_day(add_months(trunc(sysdate, 'Month'), -level +1)) monthEnd
from dual
connect by level <= 6
) months
left join yourTable
on calldate between monthStart and monthEnd
group by to_char(monthStart, 'yyyymm')
order by to_char(monthStart, 'yyyymm')
给出了:
COUNT(CALLDATE) TO_CHA
--------------- ------
1 201612
0 201701
1 201702
2 201703
1 201704
2 201705
6 rows selected.
这主要是基于一系列相关月份的开始和结束日的构建:
SQL> select add_months(trunc(sysdate, 'Month'), -level +1) monthStart,
2 last_day(add_months(trunc(sysdate, 'Month'), -level +1)) monthEnd
3 from dual
4 connect by level <= 6;
MONTHSTAR MONTHEND
--------- ---------
01-MAY-17 31-MAY-17
01-APR-17 30-APR-17
01-MAR-17 31-MAR-17
01-FEB-17 28-FEB-17
01-JAN-17 31-JAN-17
01-DEC-16 31-DEC-16
6 rows selected.
答案 1 :(得分:0)
你可以尝试这样的事情:
select TO_CHAR(CALLDATE,'yyyymm'),count(*)
from yourTable
--filter last n months (in this case 7)
where CALLDATE> SYSDATE - INTERVAL '7' MONTH
--group by month
group by TO_CHAR(CALLDATE,'yyyymm');
如果您在没有通话的情况下需要零个月:
WITH MONTH_COUNTER AS (
SELECT LEVEL-1 AS ID
FROM DUAL
CONNECT BY LEVEL <= 6
), all_month as (
--last 6 months
SELECT TO_CHAR(ADD_MONTHS(sysdate, -ID),'yyyymm') m FROM MONTH_COUNTER
), all_count as (
--previous query
select TO_CHAR(CALLDATE,'yyyymm') m,count(*) c
from yourTable
where CALLDATE> SYSDATE - INTERVAL '7' MONTH
group by TO_CHAR(CALLDATE,'yyyymm')
)
--nvl = when count(*) is null then put 0
select all_month.m,nvl(all_count.c,0)
from all_month
left outer join all_count
on all_month.m = all_count.m;