我有一个问题需要在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
相同,那么它的相同部分{{1} }}
答案 0 :(得分: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
实际上存储为日期而不是字符串。如果是字符串,那么排序将不正确。转换为日期或使用指定正确排序的列。
答案 1 :(得分:0)
以下是使用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
对它们进行排序。然后它搜索模式:一行,标记为a
,没有约束,后面是零行或多行b
,其中b
由value
的条件定义}与prev [ious]行相同。该子句计算的内容或measures
是match_number()
- 模式的第一个“匹配”,第二个匹配等。我们在外部查询中使用此匹配编号作为组编号(grp
) - 这就是我们所需要的一切!
* Notes :这样的解决方案的存在表明了为什么海报说明他们的Oracle版本很重要。 (运行语句select * from v$version
以查找。)另外:date
和group
是Oracle中的保留字,不应用作列名。甚至没有发布制作样本数据。 (有一些解决方法,但在这种情况下不需要它们。)另外,每当在帖子中使用03/01/2017等日期时,请说明是3月1日还是1月3日,“我们”无法告诉。 (在这种情况下并不重要,但在绝大多数情况下都是如此。)