[英]sql query to get unique id for a row in oracle based on its continuity
我有一个需要在oracle中使用sql解决的问题。
我有一个如下所示的数据集:
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
。
这是使用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
实际上存储为日期而不是字符串。 如果是字符串,则排序将不正确。 要么转换为日期,要么使用指定正确顺序的列。
这是使用Oracle 12. *中引入的MATCH_RECOGNIZE
子句的解决方案。
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
对其进行dt
。 然后,它搜索模式:标记为a
一行,没有任何约束,紧接着是零个或多个行b
,其中b
由条件确定,即value
与上一行相同。 该子句计算或measures
是match_number()
-模式的第一个“匹配”,第二个匹配等。我们将这个匹配号用作外部查询中的组号( grp
)-这就是我们所需要的!
*注意 :这样的解决方案的存在说明了为什么张贴者声明其Oracle版本很重要。 (运行语句select * from v$version
进行查找。)另外: date
和group
是Oracle中的保留字,不应用作列名。 甚至不用于发布虚构的样本数据。 (有解决方法,但在这种情况下是不需要的。)此外,每当在帖子中使用日期如03/01/2017时,请指出是3月1日还是1月3日,“我们”无法告诉。 (在这种情况下这并不重要,但在绝大多数情况下都是如此。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.