2017-02-04 38 views
0

我有一个问题需要在oracle中使用sql来解决。sql查询根据其连续性在oracle中为某行获取唯一标识

我有一个数据集类似如下:

value | date 
------------- 
1 | 01/01/2017 
2 | 02/01/2017 
3 | 03/01/2017 
3 | 04/01/2017 
2 | 05/01/2017 
2 | 06/01/2017 
4 | 07/01/2017 
5 | 08/01/2017 

我需要显示的结果在下面的格式:

value | date  | Group 
1 | 01/01/2017 | 1 
2 | 02/01/2017 | 2 
3 | 03/01/2017 | 3 
3 | 04/01/2017 | 3 
2 | 05/01/2017 | 4 
2 | 06/01/2017 | 4 
4 | 07/01/2017 | 5 
5 | 08/01/2017 | 6 

的逻辑是,每当value变化超过date,它被分配一个新的group/id,但如果它与前一个相同,那么它的部分相同group

+0

什么是将您转换成您想要的内容的逻辑? – BobC

+0

逻辑是每当值发生变化时它就被赋予一个新的组/ id,但是如果它与前一个相同,那么它就是同一个组的一部分。希望这可以帮助。 – amit

+0

阿米特 - 你在评论中的内容实际上应该添加到你的文章中。我这次为你做了这件事,但请记住,对于将来 - 任何进一步的要求,输入或输出的澄清,以及你提供的附加代码等都应该放在你的文章中;使用评论只是为了提醒其他人你修改了帖子。谢谢! – mathguy

回答

0

下面是使用lag()和累加和一个方法:

select t.*, 
     sum(case when value = prev_value then 0 else 1 end) over (order by date) as grp 
from (select t.*, 
      lag(value) over (order by date) as prev_value 
     from t 
    ) t; 

这里的逻辑是简单地的次数计数,从一个月值改变到下一个。

这里假定date实际上是作为日期而不是字符串存储的。如果它是一个字符串,那么排序将不正确。转换为日期或使用指定正确顺序的列。

+0

非常感谢您的帮助 – amit

0

下面是一个使用MATCH_RECOGNIZE条款的解决方案,在甲骨文12 *

select value, dt, mn as grp 
from inputs 
match_recognize (
    order by dt 
    measures match_number() as mn 
    all rows per match 
    pattern (a b*) 
    define b as value = prev(value) 
) 
order by dt -- if needed 
; 

介绍这里是如何工作的:除了SELECT,FROM和ORDER BY,查询只有一个条款,MATCH_RECOGNIZE。这个子句的作用是:从inputs开始的行,它通过dt排序。然后它搜索模式:一行,标记为a,没有约束,后面是零行或更多行b,其中bvalue与prev [ious]行相同的条件定义。条款计算的或measuresmatch_number() - 模式的第一次“匹配”,第二次匹配等。我们使用此匹配号作为外部查询中的组号(grp) - 这就是我们需要的!

*注意事项:这样的解决方案的存在说明了为什么海报声明他们的Oracle版本很重要。 (运行语句select * from v$version查找。)另外:dategroup是Oracle中的保留字,不应用作列名称。甚至没有发布构成的样本数据。 (有解决方法,但在这种情况下不需要它们。)另外,每当在帖子中使用03/01/2017等日期时,请说明是3月1日还是1月3日,“我们”无法说出。 (这种情况并不重要,但在绝大多数情况下都是如此。)