SQL范围介于过去日期和无限前置之间

时间:2014-10-01 08:08:29

标签: sql oracle range window-functions

表结构如下

country_id | ID | date | same_week_count

我对周数感兴趣,所以我在最终输出中提取它。

我想知道在每个国家/地区之前,ID出现了多少次,所以我正在使用

count(ID) OVER (PARTITION BY country_id, ID ORDER BY to_number(date, 'IW') RANGE UNBOUNDED PRECEDING) as ttl_count

但我得到以下内容:

 country_id  |  ID   |  date  | same_week_count | ttl_count
------------------------------------------------------------
   1         |  123  |   35   |   2             |   1
   1         |  123  |   35   |   2             |   3 

3来自哪里?无限追随者是否包括当前一周?我应该有一个类似于RANGE BETWEEN to_number(date, 'IW')-1 PRECEDING AND UNBOUNDED PRECEDING的表达式吗?

1 个答案:

答案 0 :(得分:2)

当您编写RANGE UNBOUNDED PRECEDING时,它是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW的快捷语法。

因此,您的RANGE UNBOUNDED PRECEDING 包含当前的周数。给定行上的计数将包括所有行(在分区内)具有与行本身相同的周数或更少 - 即使这些行实际上在行之后本身。这是RANGE BETWEEN的定义 - 否则ROWS BETWEEN可能是另一种选择。

但是,如果您希望每个分区中具有少于相同周数的那些行的计数,您将需要使用RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING之类的内容,其中包括周数,包括 1少于当前行

你遇到的另一个问题是你跨越一年会发生什么?这仅仅意味着在一个日历年内用于数据吗?在2015年的第3周,您是否希望包含2014年第51周的数据?如果是,那么请注意TO_NUMBER表达式 - 可能更好地执行TRUNC(date,'IW'),如下所示:

count(ID) OVER (
  PARTITION BY country_id, ID
  ORDER BY trunc(date, 'IW')
  RANGE BETWEEN UNBOUNDED PRECEDING AND 7 PRECEDING
) as ttl_count

TRUNC使日期成为每周的星期一。 7 PRECEDING之前 7天