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 序列?

在 ubuntu 的 Oracle Sql 中,如何打开编辑器来编写 PL/SQL?

如何在 Oracle PL/SQL 中执行存储函数

oracle sql pl/sql 如何减去日期/工作周

Oracle PL/SQL:如何在长包中查找未使用的变量?

如何一键提示两个命令? pl/sql oracle 10g 表单生成器