问题描述
嗨,汤姆,
我寻求你的帮助,如何比较表中的两行,如果它们是相同的合并行。
数据集将是
如您所见,记录2和记录3列1、2、3值相同。这些记录需要合并为1条记录,其中最小开始日期为记录2,最大结束日期为记录3。
预期结果集如下
我们如何在sql语句中实现这一点。
非常感谢您的帮助。
提前谢谢。
我寻求你的帮助,如何比较表中的两行,如果它们是相同的合并行。
create table test(id number, start_date date, end_date date, col1 varchar2(10), col2 varchar2(10), col3 varchar2(10));
insert into test values(1, to_date('01/01/1900', 'mm/dd/yyyy'), to_date('05/01/2006', 'mm/dd/yyyy'), 'a', 'b', 'a');
insert into test values(1, to_date('05/02/2006', 'mm/dd/yyyy'), to_date('06/01/2006', 'mm/dd/yyyy'), 'x', 'y', 'z');
insert into test values(1, to_date('07/01/2006', 'mm/dd/yyyy'), to_date('07/01/2016', 'mm/dd/yyyy'), 'x', 'y', 'z');
insert into test values(1, to_date('08/01/2016', 'mm/dd/yyyy'), to_date('09/01/2016', 'mm/dd/yyyy'), 'x', 'b', 'a');
insert into test values(1, to_date('10/01/2016', 'mm/dd/yyyy'), to_date('12/31/2020', 'mm/dd/yyyy'), 'a', 'b', 'a');数据集将是
id start date end date col1 col2 col3 1 01/01/1900 05/01/2006 a b c 1 05/02/2006 06/01/2006 x y z ------ record 2 1 07/01/2006 07/01/2016 x y z ------ record 3 1 08/01/2016 09/01/2016 x b a 1 10/01/2016 12/31/2016 a b c
如您所见,记录2和记录3列1、2、3值相同。这些记录需要合并为1条记录,其中最小开始日期为记录2,最大结束日期为记录3。
预期结果集如下
id start date end date col1 col2 col3 1 01/01/1900 05/01/2006 a b c 1 05/02/2006* 07/01/2016* x y z ------ 2 and 3 merged with min and max dates 1 08/01/2016 09/01/2016 x b a 1 10/01/2016 12/31/2016 a b c
我们如何在sql语句中实现这一点。
非常感谢您的帮助。
提前谢谢。
专家解答
我不清楚您如何确切地定义要分组的X,Y,Z行,而不是A,B,C行。是在上一个结束和下一个开始之间有一个月的时间吗?
你需要明确这个匹配是如何工作的,以获得一个完整的解决方案。
但无论如何:
模式匹配 (匹配 _ 识别) 到救援!
使用它来定义一个模式变量,该变量提供了合并行的标准。如果结束日期和开始日期之间正好有一个月,我已经假设您将它们组合在一起。根据需要对您的数据进行调整。
然后,这只是搜索后面有这个变量的任何行的问题。同样,我假设有许多连续的行要合并它们。如果不是这种情况,请将正则表达式量词从匹配任意行数 (*/星号) 更改为零到N。例如,如果要合并最多两行,请使用以下模式:
所有这些都给出了:
Stew Ashton在以下位置更详细地讨论了合并连续日期范围的挑战:https://stewashton.wordpress.com/2014/03/16/merging-contiguous-date-ranges/
如果你正在寻找更多关于模式匹配的背景,你可以在我的答案中找到更多的例子:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9533477800346658909
或者我关于这个主题的幻灯片:https://www.slideshare.net/ChrisSaxon1/how-to-find-patterns-in-your-data-with-sql
你需要明确这个匹配是如何工作的,以获得一个完整的解决方案。
但无论如何:
模式匹配 (匹配 _ 识别) 到救援!
使用它来定义一个模式变量,该变量提供了合并行的标准。如果结束日期和开始日期之间正好有一个月,我已经假设您将它们组合在一起。根据需要对您的数据进行调整。
然后,这只是搜索后面有这个变量的任何行的问题。同样,我假设有许多连续的行要合并它们。如果不是这种情况,请将正则表达式量词从匹配任意行数 (*/星号) 更改为零到N。例如,如果要合并最多两行,请使用以下模式:
strt consecutive{0,1}所有这些都给出了:
select *
from test match_recognize (
partition by id, col1, col2, col3
order by start_date
measures
first ( start_date ) as st,
last ( end_date ) as en
pattern ( strt consecutive* )
define
consecutive as
start_date = add_months (
prev ( end_date ), 1
)
)
order by st, en;
ID COL1 COL2 COL3 ST EN
1 a b a 01-JAN-1900 00:00:00 01-MAY-2006 00:00:00
1 x y z 02-MAY-2006 00:00:00 01-JUL-2016 00:00:00
1 x b a 01-AUG-2016 00:00:00 01-SEP-2016 00:00:00
1 a b a 01-OCT-2016 00:00:00 31-DEC-2020 00:00:00 Stew Ashton在以下位置更详细地讨论了合并连续日期范围的挑战:https://stewashton.wordpress.com/2014/03/16/merging-contiguous-date-ranges/
如果你正在寻找更多关于模式匹配的背景,你可以在我的答案中找到更多的例子:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9533477800346658909
或者我关于这个主题的幻灯片:https://www.slideshare.net/ChrisSaxon1/how-to-find-patterns-in-your-data-with-sql
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




