1

我有一个名为的表PRODUCTS,每个表PRODUCT_NO_REGISTRATION_NO只允许使用一次,即产品开始日期和退货日期不应冲突。

我们退回产品并输入退货日期ACTUAL_RETURN_DATE,如果ACTUAL_RETURN_DATE为空,我们将END_DATE其作为退货日期。

你可以在这里看到记录

例如PRODUCT_NO_REGISTRATION_NO is clashing, as HP_2014 is returned on 18-Jun-2001, however HP_2012 same PRODUCT_NO_REGISTRATION_NO is allotted on 18-Jun-2001.

如何使用 sql 找出记录是否重叠?

更新 1

表中进行了修改PRODUCTS以包含PRODUCT_EXTENSION_NO. 的组合PRODUCT_NO,PRODUCT_NO_REGISTRATION_NO and PRODUCT_EXTENSION_NO成为唯一的行(复合主键)。

规则如下 每个PRODUCT_NO_REGISTRATION_NO只允许使用一次,即产品开始日期和退货日期不应冲突。

我们退回产品并输入退货日期ACTUAL_RETURN_DATE,如果ACTUAL_RETURN_DATE为空,我们将END_DATE其作为退货日期。

PRODUCT_NO有扩展,所以END_DATE是扩展的。

Sql 小提琴

例如,如果您看到记录 PRODUCT_NO- ORP76with PRODUCT_EXTENSION_NO-与- with -1发生冲突。PRODUCT_NOORP100PRODUCT_EXTENSION_NO0

如何使用 sql 找出记录是否重叠,PRODUCT_NO但是否允许扩展。ie PRODUCT_NO ORP76with extension0和extension 1基本上都是扩展的。

4

1 回答 1

1

假设这product_no是唯一的,您可以自连接 products 表并检查重叠日期

select *
  from PRODUCTS
 inner join products products_test
    on products.PRODUCT_NO_REGISTRATION_NO 
     = products_test.PRODUCT_NO_REGISTRATION_NO
   and products.start_date 
    <= nvl (products_test.ACTUAL_RETURN_DATE, products_test.end_date)
   and nvl (products.ACTUAL_RETURN_DATE, products.end_date) 
    >= products_test.start_date
   and products.product_no 
    <> products_test.product_no

这是 Sql Fiddle

编辑:使用 rowid 的版本:

select *
  from PRODUCTS
 inner join products products_test
    on products.PRODUCT_NO_REGISTRATION_NO 
     = products_test.PRODUCT_NO_REGISTRATION_NO
   and products.start_date 
    <= nvl (products_test.ACTUAL_RETURN_DATE, products_test.end_date)
   and nvl (products.ACTUAL_RETURN_DATE, products.end_date) 
    >= products_test.start_date
   and products.rowid
    <> products_test.rowid

第二个 Sql 小提琴

澄清后更新:想法是在记录中获取产品开始和结束日期计数的最小和最大范围extended,然后通过测试 product_no 和 product_no_registration_no 比较两个流的范围重叠消除自我引用。

with extended as
(
  select PRODUCT_NO, 
         PRODUCT_NO_REGISTRATION_NO, 
         min (START_DATE) as start_date,
         max (nvl (ACTUAL_RETURN_DATE, END_DATE)) as end_date
    from products
   group by PRODUCT_NO, PRODUCT_NO_REGISTRATION_NO
)
select e1.PRODUCT_NO_REGISTRATION_NO,
       e1.PRODUCT_NO,
       e1.start_date,
       e1.end_date,
       e2.PRODUCT_NO "PRODUCT_NO - CLASH",
       e2.start_date "START_DATE - CLASH",
       e2.end_date "END_DATE - CLASH"
  from extended e1
 inner join extended e2
    on e1.PRODUCT_NO_REGISTRATION_NO
     = e2.PRODUCT_NO_REGISTRATION_NO
   and e1.start_date <= e2.end_date
   and e1.end_date >= e2.start_date
-- Remove self-references
   and not
   (
           e1.PRODUCT_NO = e2.PRODUCT_NO
       and e1.PRODUCT_NO_REGISTRATION_NO 
         = e2.PRODUCT_NO_REGISTRATION_NO
   )

第三个 Sql Fiddle

于 2012-07-30T11:53:16.213 回答