Oracle SQL - 如何在没有 PL/SQL 的情况下检查合同的延续
Posted
技术标签:
【中文标题】Oracle SQL - 如何在没有 PL/SQL 的情况下检查合同的延续【英文标题】:Oracle SQL - how to check continuation of contracts without PL/SQL 【发布时间】:2017-07-28 08:20:16 【问题描述】:我想检查由CONTRACT_ID
划分的合同的连续性,但我只想检查 FLG = 0 的合同并按整个范围(与FLG=1
)进行比较。例如,我将从 FLG=1
的行中获取第一个 date_to 并按每个日期范围进行比较。如果 date_to 在某个范围之间,那么我想对合同进行限定。下一个 date_to 和同样的情况。我不知道如何解决这个问题。一个大问题是我不能使用 PL/SQL。我可以用 SQL 来做吗?有人知道如何通过contract_id检查分区中合同的连续性吗?我不知道如何对分区中的记录进行排序。我尝试了一些代码,我正在放弃......
感谢您的每一个帮助。
| CONTRAC_ID | DATE_FROM | DATE_TO | FLG |
|------------ |----------------------- |----------------------- |--------- |
| 1 | 2016-01-01 00:00:00.0 | 2016-03-11 00:00:00.0 | 1 |
| 1 | 2016-04-15 00:00:00.0 | 2016-06-05 00:00:00.0 | 1 |
| 1 | 2016-05-10 00:00:00.0 | 2016-07-25 00:00:00.0 | 1 |
| 1 | 2016-07-25 00:00:00.0 | 2016-08-22 00:00:00.0 | 0 |
| 1 | 2017-01-19 00:00:00.0 | 2017-05-21 00:00:00.0 | 0 |
| 1 | 2017-03-05 00:00:00.0 | 2017-04-30 00:00:00.0 | 0 |
编辑:
在示例中: 我们有三个 FLG=0 的记录,所以我们在某个订单后获取第一个 date_to。我将使用“2016-08-22”,正确的程序应该检查每个日期范围的日期:
'2016-08-22' between '2016-01-01 00:00:00.0' AND '2016-03-11 00:00:00.0'
'2016-08-22' between '2016-04-15 00:00:00.0' AND '2016-06-05 00:00:00.0'
'2016-08-22' between '2016-05-10 00:00:00.0' AND '2016-07-25 00:00:00.0'
'2016-08-22' between '2017-01-19 00:00:00.0' AND '2017-05-21 00:00:00.0'
'2016-08-22' between '2017-03-05 00:00:00.0' AND '2017-04-30 00:00:00.0'
如果这些条件之一为 TRUE,则合同符合条件,否则不符合条件。
正确的SELECT
语句结果:
| CONTRAC_ID | DATE_FROM | DATE_TO | FLG | QUAL|
|------------ |----------------------- |----------------------- |--------- |-----|
| 1 | 2016-01-01 00:00:00.0 | 2016-03-11 00:00:00.0 | 1 | 1 |
| 1 | 2016-04-15 00:00:00.0 | 2016-06-05 00:00:00.0 | 1 | 1 |
| 1 | 2016-05-10 00:00:00.0 | 2016-07-25 00:00:00.0 | 1 | 1 |
| 1 | 2016-07-25 00:00:00.0 | 2016-08-22 00:00:00.0 | 0 | 0 |
| 1 | 2017-01-19 00:00:00.0 | 2017-05-21 00:00:00.0 | 0 | 0 |
| 1 | 2017-03-05 00:00:00.0 | 2017-04-30 00:00:00.0 | 0 | 1 |
最后一个合约将是合格的,因为'2017-04-30 00:00:00.0'
在一个范围之间:
2017-01-19 00:00:00.0 | 2017-05-21 00:00:00.0
前三行有 1 个因为 FLG=1
【问题讨论】:
您使用的是哪个版本的 Oracle?由于 MATCH RECOGNIZE 功能,使用 12c 处理这类事情要容易得多。 不幸的是 Oracle 11g MATCH RECOGNIZE 比较当前行的下一个或上一个值,我需要检查每个 date_to 与所有日期范围。 实际上 MATCH RECOGNIZE 比您想象的要灵活得多。 无论如何,如果您要使用要比较的行注释样本数据,哪些行符合条件,哪些行不符合条件,这会有所帮助。另外,请解释您所说的使合同符合条件的意思。在 SELECT 语句中会是什么样子? 【参考方案1】:如果我理解正确,您正在查找 FLG=1 的记录,并且您可以找到另一条记录,其中 date_from 列的值位于该另一条记录的日期范围内。
不知道您如何识别单个记录,因此我假设它们有一个 ID 列,并且您的表名为 CONTRACTS。
select ID
from contracts c1
where c1.FLG=1
and exists
(select 1
from contracts c2
where c1.contrac_id=c2.contrac_id
and c1.ID != c2.ID
and c1.date_from between c2.date_from and c2.date_to)
【讨论】:
FLG=1 的记录,它们在之前的条件之后是合格的。现在我想检查 FLG=0 的 date_to 是否在任何日期范围之间。如果是,我需要记录这些记录。 当一个记录具有长期范围时会出现问题,例如。 2016-01-01 - 2019-01-01 并且应该记录所有记录。代码排除了长期记录,也应该带他。以上是关于Oracle SQL - 如何在没有 PL/SQL 的情况下检查合同的延续的主要内容,如果未能解决你的问题,请参考以下文章
如何在一组行之后或有条件地在没有 PL/SQL 块的情况下增加 oracle 序列?