Sql 在Oracle中按日期更新计数

Sql 在Oracle中按日期更新计数,sql,oracle,plsql,oracle11g,oracle10g,Sql,Oracle,Plsql,Oracle11g,Oracle10g,我有一个奇怪的要求。给你。我有一张桌子 DateTime PhoneNo Network ------------------- -------- --------- 11/01/2014 13:05:45 99999999 NetTwo 11/01/2014 13:05:45 99999999 NetOne 11/01/2014 13:05:45 99999999 NetOne 12/01/2014 13:05

我有一个奇怪的要求。给你。我有一张桌子

DateTime               PhoneNo     Network
-------------------    --------    ---------
11/01/2014 13:05:45    99999999    NetTwo
11/01/2014 13:05:45    99999999    NetOne
11/01/2014 13:05:45    99999999    NetOne
12/01/2014 13:05:45    99999999    NetOne
12/01/2014 13:06:45    99999999    NetOne
12/01/2014 13:07:45    88888888    NetTwo
12/01/2014 13:08:45    77777777    NetThree
我必须通过每天运行一次存储过程来更新另一个表,这样它可以计算一个调用方一天调用的次数的摘要,并且应该将它更新到相应的列

目标表格:

Date        Month year    Phone     Network    01 02 03 -------11-12---30-31
11/01/2014  JAN   2014    99999999  NetOne     0   0  0        2  0    0  0
11/01/2014  JAN   2014    99999999  NetTwo     0   0  0        1  0    0  0
12/01/2014  JAN   2014    99999999  NetTwo     0   0  0        0  2    0  0
12/01/2014  JAN   2014    88888888  NetTwo     0   0  0        0  1    0  0
12/01/2014  JAN   2014    77777777  NetTwo     0   0  0        0  1    0  0
这里01到31是独立的列。如果我没有解释清楚,我道歉


任何建议或方法如何实现这一点..感谢你们耐心地研究我的问题,伙计们。任何帮助都将不胜感激。

这并不奇怪,它被称为透视表

这是一条路要走

select  trunc(DateTime) as date , to_char(datetimem,'MON') as month , to_number(to_char(datetime,'yyyy')) as year , PhoneNo, network , 
    sum(case when to_char(DateTime,'hh24') = 0 then 1 else 0 end) as h00, 
    sum(case when to_char(DateTime,'hh24') = 1 then 1 else 0 end) as h01, 
    .. 
    sum(case when to_char(DateTime,'hh24') = 23 then 1 else 0 end) as h23
from    calls_tables
group by trunc(DateTime) , to_char(datetimem,'MON'), to_number(to_char(datetime,'yyyy')) , PhoneNo, network
11g还具有枢轴功能


您应该对它进行搜索。

对于定期更新,最好使用语句

首先,以下代码示例的初始设置:

create table SourceTable(
  DateTime date,
  PhoneNo  varchar2(40),
  Network  varchar2(20)
);

create table DestinationTable(
  CallDate  date,      
  CallMonth varchar2(20),
  CallYear  number,  
  Phone     varchar2(40),
  Network   varchar2(20), 
  d01       number,
  d02       number,
  d03       number,
  d04       number,
  d05       number,
  d06       number,
  d07       number,
  d08       number,
  d09       number,
  d10       number,
  d11       number,
  d12       number,
  d13       number,
  d14       number,
  d15       number,
  d16       number,
  d17       number,
  d18       number,
  d19       number,
  d20       number,
  d21       number,
  d22       number,
  d23       number,
  d24       number,
  d25       number,
  d26       number,
  d27       number,
  d28       number,
  d29       number,
  d30       number,
  d31       number
);  
更改字段名称以符合标准命名规则

中提供的架构设置和代码

接下来,查询以演示从源表中提取日期和时间部分以处理目标:

select
  trunc(call_log.DateTime)                                      CallDate,
  to_char(call_log.DateTime,'MON','NLS_DATE_LANGUAGE=ENGLISH')  CallMonth,
  extract(year from call_log.DateTime)                          CallYear,
  extract(day from call_log.DateTime)                           CallDay,
  PhoneNo                                                       Phone,
  Network                                                       Network
from 
  SourceTable call_log
order by 
  datetime, phoneno, network
根据日期、网络和电话号码,可以对源表中的数据进行分组,并生成用于合并的源数据:

select 
  CallDate, 
  to_char(CallDate,'MON','NLS_DATE_LANGUAGE=ENGLISH')  CallMonth,
  extract(year from CallDate)                          CallYear,
  d01, d02, d03, d04, d05, d06, d07, d08, d09, d10,
  d11, d12, d13, d14, d15, d16, d17, d18, d19, d20,
  d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 
from (
  select 
    CallDate, 
    Phone, 
    Network,
    sum(decode(callDay, 1,1,0)) d01,
    sum(decode(callDay, 2,1,0)) d02,
    sum(decode(callDay, 3,1,0)) d03,
    sum(decode(callDay, 4,1,0)) d04,
    sum(decode(callDay, 5,1,0)) d05,
    sum(decode(callDay, 6,1,0)) d06,
    sum(decode(callDay, 7,1,0)) d07,
    sum(decode(callDay, 8,1,0)) d08,
    sum(decode(callDay, 9,1,0)) d09,
    sum(decode(callDay,10,1,0)) d10,
    sum(decode(callDay,11,1,0)) d11,
    sum(decode(callDay,12,1,0)) d12,
    sum(decode(callDay,13,1,0)) d13,
    sum(decode(callDay,14,1,0)) d14,
    sum(decode(callDay,15,1,0)) d15,
    sum(decode(callDay,16,1,0)) d16,
    sum(decode(callDay,17,1,0)) d17,
    sum(decode(callDay,18,1,0)) d18,
    sum(decode(callDay,19,1,0)) d19,
    sum(decode(callDay,20,1,0)) d20,
    sum(decode(callDay,21,1,0)) d21,
    sum(decode(callDay,22,1,0)) d22,
    sum(decode(callDay,23,1,0)) d23,
    sum(decode(callDay,24,1,0)) d24,
    sum(decode(callDay,25,1,0)) d25,
    sum(decode(callDay,26,1,0)) d26,
    sum(decode(callDay,27,1,0)) d27,
    sum(decode(callDay,28,1,0)) d28,
    sum(decode(callDay,29,1,0)) d29,
    sum(decode(callDay,30,1,0)) d30,
    sum(decode(callDay,31,1,0)) d31
  from (
    select
      trunc(call_log.DateTime)            CallDate,
      extract(day from call_log.DateTime) CallDay,
      PhoneNo                             Phone,
      Network                             Network
    from 
      SourceTable call_log
  )
  group by 
    CallDate, Phone, Network
)  
order by 
  CallDate, Phone, Network
最后一步是将准备好的数据合并到目标表中:

merge into DestinationTable call_totals
using (
  select       -- Previous select (removed unneeded columns and ordering)
    CallDate, 
    Phone, 
    Network,
    sum(decode(callDay, 1,1,0)) d01,
    sum(decode(callDay, 2,1,0)) d02,
    sum(decode(callDay, 3,1,0)) d03,
    sum(decode(callDay, 4,1,0)) d04,
    sum(decode(callDay, 5,1,0)) d05,
    sum(decode(callDay, 6,1,0)) d06,
    sum(decode(callDay, 7,1,0)) d07,
    sum(decode(callDay, 8,1,0)) d08,
    sum(decode(callDay, 9,1,0)) d09,
    sum(decode(callDay,10,1,0)) d10,
    sum(decode(callDay,11,1,0)) d11,
    sum(decode(callDay,12,1,0)) d12,
    sum(decode(callDay,13,1,0)) d13,
    sum(decode(callDay,14,1,0)) d14,
    sum(decode(callDay,15,1,0)) d15,
    sum(decode(callDay,16,1,0)) d16,
    sum(decode(callDay,17,1,0)) d17,
    sum(decode(callDay,18,1,0)) d18,
    sum(decode(callDay,19,1,0)) d19,
    sum(decode(callDay,20,1,0)) d20,
    sum(decode(callDay,21,1,0)) d21,
    sum(decode(callDay,22,1,0)) d22,
    sum(decode(callDay,23,1,0)) d23,
    sum(decode(callDay,24,1,0)) d24,
    sum(decode(callDay,25,1,0)) d25,
    sum(decode(callDay,26,1,0)) d26,
    sum(decode(callDay,27,1,0)) d27,
    sum(decode(callDay,28,1,0)) d28,
    sum(decode(callDay,29,1,0)) d29,
    sum(decode(callDay,30,1,0)) d30,
    sum(decode(callDay,31,1,0)) d31
  from (
    select
      trunc(call_log.DateTime)            CallDate,
      extract(day from call_log.DateTime) CallDay,
      PhoneNo                             Phone,
      Network                             Network
    from 
      SourceTable call_log
  )
  group by 
    CallDate, Phone, Network
) existing_calls
on (                
  -- Link prepared data from source table to destination
  call_totals.CallDate = existing_calls.CallDate
  and
  call_totals.Phone = existing_calls.Phone
  and
  call_totals.Network = existing_calls.Network
)
when matched then
  -- If record for date, phone and record found - update statistics
  update
    set
      d01 = existing_calls.d01,
      d02 = existing_calls.d02,
      d03 = existing_calls.d03,
      d04 = existing_calls.d04,
      d05 = existing_calls.d05,
      d06 = existing_calls.d06,
      d07 = existing_calls.d07,
      d08 = existing_calls.d08,
      d09 = existing_calls.d09,
      d10 = existing_calls.d10,
      d11 = existing_calls.d11,
      d12 = existing_calls.d12,
      d13 = existing_calls.d13,
      d14 = existing_calls.d14,
      d15 = existing_calls.d15,
      d16 = existing_calls.d16,
      d17 = existing_calls.d17,
      d18 = existing_calls.d18,
      d19 = existing_calls.d19,
      d20 = existing_calls.d20,
      d21 = existing_calls.d21,
      d22 = existing_calls.d22,
      d23 = existing_calls.d23,
      d24 = existing_calls.d24,
      d25 = existing_calls.d25,
      d26 = existing_calls.d26,
      d27 = existing_calls.d27,
      d28 = existing_calls.d28,
      d29 = existing_calls.d29,
      d30 = existing_calls.d30,
      d31 = existing_calls.d31
when not matched then 
  -- If record for date, phone and record not found - add new one
  insert (
    CallDate, CallMonth, CallYear, Phone, Network,
    d01, d02, d03, d04, d05, d06, d07, d08, d09, d10,
    d11, d12, d13, d14, d15, d16, d17, d18, d19, d20,
    d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 
  ) values (
    existing_calls.CallDate,
    to_char(existing_calls.CallDate, 'MON', 'NLS_DATE_LANGUAGE=ENGLISH'),
    extract( year from existing_calls.CallDate),
    existing_calls.Phone,
    existing_calls.Network,
    existing_calls.d01, 
    existing_calls.d02, 
    existing_calls.d03, 
    existing_calls.d04, 
    existing_calls.d05, 
    existing_calls.d06, 
    existing_calls.d07, 
    existing_calls.d08, 
    existing_calls.d09, 
    existing_calls.d10,
    existing_calls.d11, 
    existing_calls.d12, 
    existing_calls.d13, 
    existing_calls.d14, 
    existing_calls.d15, 
    existing_calls.d16, 
    existing_calls.d17, 
    existing_calls.d18, 
    existing_calls.d19, 
    existing_calls.d20,
    existing_calls.d21, 
    existing_calls.d22, 
    existing_calls.d23, 
    existing_calls.d24, 
    existing_calls.d25, 
    existing_calls.d26, 
    existing_calls.d27, 
    existing_calls.d28, 
    existing_calls.d29, 
    existing_calls.d30, 
    existing_calls.d31 
  )
;

非常感谢你的努力。谢谢haki和Thinkjet@思考:我从你那里学到了合并:D

我使用with子句的结果集中的子查询得到了预期的结果

WITH MainFilter(CLI,DAYS,COUNTS)
AS (SELECT TBL_DTL_CALLACTIVITY.CLI,
TO_CHAR(TBL_DTL_CALLACTIVITY.CALLSTARTTIME, 'DD'),COUNT(TBL_DTL_CALLACTIVITY.CLI)
FROM TBL_DTL_CALLACTIVITY 
WHERE  UPPER(TO_CHAR(TBL_DTL_CALLACTIVITY.CALLSTARTTIME, 'mon')) =UPPER(i_Month) AND
(SELECTED_DNIS IS NULL OR TBL_DTL_CALLACTIVITY.DNIS = SELECTED_DNIS) 
GROUP BY TBL_DTL_CALLACTIVITY.CLI,
TO_CHAR(TBL_DTL_CALLACTIVITY.CALLSTARTTIME,'DD'))
SELECT MF.CLI,
NVL((SELECT COUNTS FROM MainFilter WHERE MainFilter.DAYS = '01' AND CLI  = MF.CLI ),0)     AS  Day_01,
NVL((SELECT COUNTS FROM MainFilter WHERE MainFilter.DAYS = '02' AND CLI  = MF.CLI ),0) AS  Day_02,
NVL((SELECT COUNTS FROM MainFilter WHERE MainFilter.DAYS = '03' AND CLI  = MF.CLI ),0) AS  Day_03,
--------------------
--------------------
FROM MainFilter MF GROUP BY MF.CLI ;

我担心查询性能。使用这种方法好吗?

因为他有0-31,我想这是一个月中的一天,而不是一天中的一小时。此外,通过使用日历表,您可能会从查询中获得更好的性能。