2013-12-09 40 views
0

我得到了一个带有时间戳列(YYYY.MM.DD HH24:MI:SS)的源表以及每天都有聚合行的目标表(日期列:YYYY.MM.DD )。只汇总源表中的新行

我的问题是:如何将新数据从源代码带入目标并对其进行聚合?

我想:

select 
    a.Sales, 
    trunc(a.timestamp,'DD') as TIMESTAMP, 
    count(1) as COUNT, 
from 
tbl_Source a 
where trunc(a.timestamp,'DD') > nvl((select MAX(b.TIME_TO_DAY)from tbl_target b), to_date('01.01.1975 00:00:00','dd.mm.yyyy hh24:mi:ss')) 

group by a.sales, 
    trunc(a.Timestamp,'DD') 

与的问题是:当我有一排时间戳“2013年11月15日0时01分32秒”,并从目标最大的一天是月14日,它只会累计15日。我会使用> =而不是>某些行会加载两次。

回答

0

这是否适合您的需要:

WHERE trunc(a.timestamp,'DD') > nvl((select MAX(b.TIME_TO_DAY) + 1 - 1/(24*60*60) from tbl_target b), to_date('01.01.1975 00:00:00','dd.mm.yyyy hh24:mi:ss')) 

即代替2013年11月15日0点〇〇分00秒比较2013年11月16日23时59分59秒

更新

这一个?

WHERE trunc(a.timestamp,'DD') BETWEEN nvl((select MAX(b.TIME_TO_DAY) from ...) AND nvl((select MAX(b.TIME_TO_DAY) + 1 - 1/(24*60*60) from ...) 
+0

感谢您的答案,但我不这么认为。可以说在目标中,我的最大日期是14日(因为流程聚集了几行,时间戳在0点之后关闭)和源15日00:01:32。现在我需要这两次之间的所有行。 – user2428207

0

看起来你正在寻找一个MERGE语句:如果这一天是tbl_target已经存在然后更新计数否则插入记录。

merge into tbl_target dest 
using 
(
    select sales, trunc(timestamp) as theday , count(*) as sales_count 
    from tbl_Source 
    where trunc(timestamp) >= (select nvl(max(time_to_day),to_date('01.01.1975','dd.mm.yyyy')) from tbl_target) 
    group by sales, trunc(timestamp) 
) src 
on (src.theday = dest.time_to_day) 
when matched then update set 
    dest.sales_count = src.sales_count 
when not matched then 
    insert (time_to_day, sales_count) 
    values (src.theday, src.sales_count) 
; 
0

据我了解你的问题:自上次重新载入目标表以来,你需要得到一切。

问题在这里:你需要这个日期,但它在更新过程中被截断。

如果我的猜测是正确的,除了将重新加载的日期作为附加列存储之外,您无法做任何事情,因为无法从此处显示的数据中取回它。

有关查询:

  1. COUNT(*)和count(1)在性能相同的(证明了很多次,至少在10-11版) - 不要让这个数(1) ,看起来真的很丑陋
  2. 不使用NVL,使用聚结而不是它 - 它的速度要快得多
  3. 我会写你的查询这样的:

    with t as (select max(b.time_to_day) mx from tbl_target b) 
    select a.sales,trunc(a.timestamp,'dd') as timestamp,count(*) as count 
    from tbl_source a,t 
    where trunc(a.timestamp,'dd') > t.mx or t.mx is null 
    group by a.sales,trunc(a.timestamp,'dd')