在表中的某些列上计算满足某些条件的表中先前行数的动态方法

时间:2013-05-14 16:40:44

标签: sql db2

作为一个具体示例,我说我有一个表T,其中列customerdate表示个别客户购买的日期:

customer |   date   
----------------------  
       A | 01/01/2013 
       A | 02/01/2013
       A | 07/01/2013
       A | 11/01/2013
       B | 03/01/2013
       B | 08/01/2013       

我想为每对(customer, date)(c, d)添加另一列,在(c', d')中提供T的{​​{1}}对,c = c'和{ {1}}。下面是这个额外列的表格:

0 <= days(d) - days(d') <= 7

作为我用来解决这个问题的步骤的粗略概念:

  • 创建一个包含所有可能对customer | date | new_column ---------------------------------- A | 01/01/2013 | 1 A | 02/01/2013 | 2 A | 07/01/2013 | 3 A | 11/01/2013 | 2 B | 03/01/2013 | 1 B | 10/01/2013 | 1 ;
  • 的表格T'
  • 将加入(c,d)保留到T;
  • 创建新列:T';
  • 忽略count(date) over (partition by customer order by date asc rows between 6 preceding and 0 following)
  • 这个新表格中的所有行

但是,我不认为这是可扩展的。

欢呼任何帮助。

1 个答案:

答案 0 :(得分:0)

让我们从一些DDL开始。 (如果在问题中包含DDL和示例INSERT语句,您将获得更多答案和更好的答案。)

create table test (
  customer char(1) not null,
  purchase_date date not null,
  primary key (customer, purchase_date)
);

insert into test values
('A', '2013-01-01'),
('A', '2013-01-02'),
('A', '2013-01-07'),
('A', '2013-01-11'),
('B', '2013-01-03'),
('B', '2013-01-10');

在标准SQL中,您可以沿着这些行使用某些内容。它不需要创建另一个表,外部联接或窗口函数。目前尚不清楚您是否有充分理由想要创建新表,但没有必要获取正确的数据。 (我重命名了“日期”列以避免使用保留字。)

select t1.customer, t1.purchase_date, count(*) new_column
from test t1
inner join test t2 on t1.customer = t2.customer
and t2.purchase_date <= t1.purchase_date and t2.purchase_date > t1.purchase_date - interval '7 day'
group by t1.customer, t1.purchase_date
order by t1.customer, t1.purchase_date;

customer  purchase_date  new_column
--
A         2013-01-01     1
A         2013-01-02     2
A         2013-01-07     3
A         2013-01-11     2
B         2013-01-03     1
B         2013-01-10     1

这是否可以很好地扩展取决于DB2处理非equi连接的程度。 DB2 EXPLAIN将指导您。我希望“purchase_date”和限制性WHERE子句的索引表现良好。